父子进程间通信 - 保持管道打开可以吗?
Parent child interprocess comunication - is keeeping pipes open OK?
我必须实现一个程序,其中进程将从父进程接收到的数据发送到子进程,等待子进程将处理后的数据发回给他,然后 return 将处理后的数据发送给子进程(例如,在 4 个进程的情况下,数据流看起来像这样 P1->P2->P3->P4->P3->P2->P1
)。对于进程间通信的方式,我需要使用管道。这是我计划采用的方法:
./child
// Assert argv contains 2 pipe descriptors - for reading
// from parent and for writing to parent, both of type char[]
// I'm not handling system errors currently
int main(int argc, char *argv[]) {
int read_dsc, write_dsc;
read_dsc = atoi(argv[1]);
write_dsc = atoi(argv[2]);
char data[DATA_SIZE];
read (read_dsc, data, DATA_SIZE - 1);
close (read_dsc);
// Process data...
(...)
// Pass processed data further
int pipeRead[2]; // Child process will read from this pipe
int pipeWrite[2]; // Child process will write into this pipe
pipe(pipeRead);
pipe(pipeWrite);
switch(fork()) {
case 0:
close (pipeRead[1]);
close (pipeWrite[0]);
char pipeReadDsc[DSC_SIZE];
char pipeWriteDsc[DSC_SIZE];
printf (pipeReadDsc, "%d", pipeRead[0]);
printf (pipeWriteDsc, "%d", pipeWrite[1]);
execl ("./child", "child", pipeReadDsc, pipeWriteDsc, (char *) 0);
default:
close(pipeRead[0]);
close(pipeWrite[1]);
wait(0);
read (pipeWrite[0], data, DATA_SIZE - 1);
close (pipeWrite[0]);
// Pass data to parent process
write (write_dsc, data, DATA_SIZE - 1);
close (write_dsc);
}
}
我的解决方案的高级描述如下:制作 2 个管道,一个用于写入子进程,一个用于从子进程读取。等到子进程完成,然后从读取管道读取并将数据传递给父进程。
问题是我不知道这种做法是否正确。我在某处读到,不关闭未使用的管道是一个错误,因为它会使 OS 文件描述符混乱,并且不应该同时打开很多管道。然而,在这里我们正在保持未关闭的管道以从子进程读取,并且可能如果有 n
个进程,当进程号 n
处理它的数据时,有 n
个打开的管道(所有父进程都是等待数据返回)。但是我看不到任何其他方法来解决这个问题...
所以 - 我的解决方案正确吗?如果不是,我该如何解决这个问题?
是的,您的解决方案是正确的。但是你的代码有问题:
- 情况 0 是 child,您将受益于将管道末端重定向到标准输入和输出(使用
dup
或 dup2
);将描述符 ID 传递给 child 很奇怪。
- 默认是parent,所以你需要在
read
ing之前write
。
"not closing unused pipes is an error" :这不是错误,但可能会导致问题(检测通信结束将很困难或不可能),但您似乎正确地关闭了代码中所有无用的管道结束,那么好吧。一般来说,打开的管道数量并不是真正的问题,因为打开的文件...
我必须实现一个程序,其中进程将从父进程接收到的数据发送到子进程,等待子进程将处理后的数据发回给他,然后 return 将处理后的数据发送给子进程(例如,在 4 个进程的情况下,数据流看起来像这样 P1->P2->P3->P4->P3->P2->P1
)。对于进程间通信的方式,我需要使用管道。这是我计划采用的方法:
./child
// Assert argv contains 2 pipe descriptors - for reading
// from parent and for writing to parent, both of type char[]
// I'm not handling system errors currently
int main(int argc, char *argv[]) {
int read_dsc, write_dsc;
read_dsc = atoi(argv[1]);
write_dsc = atoi(argv[2]);
char data[DATA_SIZE];
read (read_dsc, data, DATA_SIZE - 1);
close (read_dsc);
// Process data...
(...)
// Pass processed data further
int pipeRead[2]; // Child process will read from this pipe
int pipeWrite[2]; // Child process will write into this pipe
pipe(pipeRead);
pipe(pipeWrite);
switch(fork()) {
case 0:
close (pipeRead[1]);
close (pipeWrite[0]);
char pipeReadDsc[DSC_SIZE];
char pipeWriteDsc[DSC_SIZE];
printf (pipeReadDsc, "%d", pipeRead[0]);
printf (pipeWriteDsc, "%d", pipeWrite[1]);
execl ("./child", "child", pipeReadDsc, pipeWriteDsc, (char *) 0);
default:
close(pipeRead[0]);
close(pipeWrite[1]);
wait(0);
read (pipeWrite[0], data, DATA_SIZE - 1);
close (pipeWrite[0]);
// Pass data to parent process
write (write_dsc, data, DATA_SIZE - 1);
close (write_dsc);
}
}
我的解决方案的高级描述如下:制作 2 个管道,一个用于写入子进程,一个用于从子进程读取。等到子进程完成,然后从读取管道读取并将数据传递给父进程。
问题是我不知道这种做法是否正确。我在某处读到,不关闭未使用的管道是一个错误,因为它会使 OS 文件描述符混乱,并且不应该同时打开很多管道。然而,在这里我们正在保持未关闭的管道以从子进程读取,并且可能如果有 n
个进程,当进程号 n
处理它的数据时,有 n
个打开的管道(所有父进程都是等待数据返回)。但是我看不到任何其他方法来解决这个问题...
所以 - 我的解决方案正确吗?如果不是,我该如何解决这个问题?
是的,您的解决方案是正确的。但是你的代码有问题:
- 情况 0 是 child,您将受益于将管道末端重定向到标准输入和输出(使用
dup
或dup2
);将描述符 ID 传递给 child 很奇怪。 - 默认是parent,所以你需要在
read
ing之前write
。
"not closing unused pipes is an error" :这不是错误,但可能会导致问题(检测通信结束将很困难或不可能),但您似乎正确地关闭了代码中所有无用的管道结束,那么好吧。一般来说,打开的管道数量并不是真正的问题,因为打开的文件...