子进程之间的UNIX管道

我正在尝试编写一个程序,它将生成任意数量的子进程并在它们之间进行管道传输,类似于命令行管道。 在我的情况下,我正在尝试“ls -l | more”并将其输出到stdout,然后让父级继续执行更多命令。

我将以下代码作为最小示例:

int main (int argc, const char * argv[]) { int fd[2]; pipe(fd); chdir("/directory/with/lots/of/files"); // Create one child process for more int pid = fork(); if (pid == 0) { close(fd[1]); int ret = dup2(fd[0],0); if (ret < 0) perror("dup2"); char *argv[10]; argv[0] = "more"; argv[1] = NULL; execvp("more", argv); } // Create another child process for ls int pid2 = fork(); if (pid2 == 0) { int ret = dup2(fd[1],1); if (ret < 0) perror("dup2"); char *argv[10]; argv[0] = "ls"; argv[1] = "-l"; argv[2] = NULL; execvp("ls", argv); } // wait for the more process to finish int status; waitpid(pid, &status, 0); printf("Done!\n"); return 0; } 

现在,当我执行程序时(当然包含在main()函数中)我最终得到的更多,这是预期的。 我会点击“d”来减少更多的输出,“u”上升,它似乎工作正常。 但是当我到达底部,而不是像更多的那样退出时,它只留下一个空白。 Ctrl-C可以退出它,但退出整个程序,意味着“完成!” 线从未打印过。 这里有一部电影可以说明会发生什么(请注意,最后我按Ctrl-C返回bash)。

有什么想法吗? 我只是想弄清楚如何将它更改为位置,而不是在更多到达底部之后转到空行,更多退出并返回到父进程,以便它可以继续执行。

您需要至少close()管道的写入端,否则more将永远不会看到EOF。 例如:

  ... // close parent's pipes close(fd[0]); close(fd[1]); // wait for the more process to finish int status; waitpid(pid, &status, 0); printf("Done!\n"); return 0; } 

我认为这是因为wait() function 。 遵循逻辑,您的第二个子进程输出到第一个子进程,这意味着它应该首先结束而不是第二个子进程。

waitfunction中,您正在等待第一个进程结束,但您不是在等待第二个进程。 这意味着如果第二个进程没有向输出发送EOF,我猜你的第一个进程将不会结束。

您可以尝试等待第二个进程而不是第一个进程,并查明是否存在问题。