[英]Piping output to forks in C
I have a multiple processes in progs and I wish to pipe the output from one process to another sequentially.我在 progs 中有多个进程,我希望 pipe output 从一个进程顺序到另一个进程。 I believe I have already linked the stdin of a process to the read end of a previous process, and linked the stdout to the write end of the pipe. I still am not seeing an output. Am I missing something with the links here?
我相信我已经将一个进程的标准输入链接到前一个进程的读取端,并将标准输出链接到 pipe 的写入端。我仍然没有看到 output。我是否遗漏了这里的链接?
int pipeFds[numProg][2];
for (int i = 0; i < numProg; i++) {
if (pipe(pipeFds[i]) != 0) { // create pipe for each process
printf("Failed to create pipe!");
exit(1);
}
child_pid = fork();
if (child_pid == -1) {
printf("Error while creating fork!");
exit(1);
}
if (child_pid == 0) {
if (i == 0) {
close(pipeFds[i][READ_END]); // close STDIN first process since it does not read
} else {
// change stdin to read end of pipe for intermediary processes
close(pipeFds[i]);
dup2(pipeFds[i - 1][READ_END], STDIN_FILENO);
}
dup2(pipeFds[i][WRITE_END], STDOUT_FILENO); // change stdout to write end of pipe
execvp(progs[i][0], (char *const * )progs[i]);
} else {
// parent process stuff
}
}
// Close pipes except last pipe for EOF
for (int i = 0; i < numProg - 1; i++) {
close(pipeFds[i][READ_END]);
close(pipeFds[i][WRITE_END]);
}
your code contains a stray close(pipeFds[i]);
您的代码包含一个杂散的
close(pipeFds[i]);
you have to close the pipes within the // parent process stuff
.你必须关闭
// parent process stuff
中的管道。 With your code, every child keeps the pipeFds
of the previous children open.使用您的代码,每个孩子都会使之前孩子的
pipeFds
保持打开状态。 Eg例如
} else { // parent process stuff if (i > 0) close(pipeFds[i - 1][READ_END]); close(pipeFds[i - 1][READ_END]); }
it might be more effective to have a single fds[2]
pair instead of numProg
ones.使用单个
fds[2]
对而不是numProg
对可能更有效。
Remember you need to close all pipes, in each process, for it to work.请记住,您需要关闭每个进程中的所有管道才能正常工作。
Example:例子:
If numProg=2
you create 2 pipes and 2 child processes.如果
numProg=2
创建 2 个管道和 2 个子进程。 Adding the parent, there a 3 processes running, and in each of them you eventually need to close all pipes.添加父级,有 3 个进程在运行,在每个进程中,您最终需要关闭所有管道。
For child_pid==0
you close the [READ_END]
but never the [WRITE_END]
.对于
child_pid==0
,您关闭[READ_END]
但永远不会关闭[WRITE_END]
。
For child_pid==1
you do a close(pipeFds[1])
.对于
child_pid==1
你做一个close(pipeFds[1])
。 You need to specify [READ_END]
and [WRITE_END]
.您需要指定
[READ_END]
和[WRITE_END]
。
Then each child process exits via execvp
which, however, may return control if it fails.然后每个子进程通过
execvp
退出,但是,如果它失败,它可能会返回控制权。 From the man page:从手册页:
The exec() family of functions replaces the current process image with a new process image. exec() 系列函数用新的过程映像替换当前过程映像。 .. The exec() functions only return if an error has occurred.
.. exec() 函数仅在发生错误时返回。
So you may want to add a _exit(0);
所以你可能想添加一个
_exit(0);
after execvp
to ensure each child process exits properly even if execvp
fails.在
execvp
之后确保每个子进程正确退出,即使execvp
失败。
The parent process closes all pipes but the last.父进程关闭除最后一个以外的所有管道。 So in the example of
NumProg=2
, [READ_END]
and [WRITE_END]
of pipeFd[1]
both are never closed.因此,在
NumProg=2
的示例中, pipeFd[1]
的[READ_END]
和[WRITE_END]
都永远不会关闭。
Lastly, the parent process should wait
for all child processes to close (using while(wait(NULL);= -1);
) otherwise you may end up with zombie or orphan processes.最后,父进程应该
wait
所有子进程关闭(使用while(wait(NULL);= -1);
),否则你可能会得到僵尸或孤儿进程。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.