c - 是否可以在同一父进程(LINUX、POSIX)创建的两个子进程之间建立管道

标签 c linux ipc pipe

我有多个子进程由同一个父进程“ fork ”,我尝试在所有这些子进程之间构建 pipe 连接,如链表结构。 child 1 将数据发送给 child 2, child 2 给 child 3 .... child N 给 child 1。有什么合适的方法吗?

此外,如果我在进程之间创建和通信,我如何强制父进程“等待”自 wait()waitpid() 以来的所有进程完成他们的工作> 等待第一个完成的过程,但我需要等待所有过程。这是另一个问题。

谢谢...

最佳答案

这本质上就是 shell 在构建重定向链时所做的事情,即类似于

ls | grep foo | sort | uniq

有一些优秀的 Unix 编程入门书籍,其中通过本书实现了一个简单的 shell。 shell 的任务之一是重定向。其中一本书是 Michael K. Johnson 和 Erik W. Troan 合着的“Linux Application Programming”。

本书主页:http://ladweb.net/

要为 N 个进程构建重定向链,您需要 N-1 个管道。对于每个重定向,您使用 pipe(int fds[2]) 系统调用创建一个管道。在 fork()ing 之后,但在 execving 之前,使用 dup2(int from, int to) 将管道的末端“连接”到标准每个进程的输入(0)或标准输出。这是一个过于简化的代码,没有错误检查:

int pipe_A[2];
int pipe_B[2];

pipe(pipe_A);
pipe(pipe_B);

pid_t pid_A, pid_B, pid_C;

if( !(pid_A = fork()) ) {
    dup2(pipe_A[1], 1); /* redirect standard output to pipe_A write end */
    execv(...);
}

if( !(pid_B = fork()) ) {
    dup2(pipe_A[0], 0); /* redirect standard input to pipe_A read end */
    dup2(pipe_B[1], 1); /* redirect standard output to pipe_B write end */
    execv(...);
}

if( !(pid_C = fork()) ) {
    dup2(pipe_B[0], 0); /* redirect standard input to pipe_B read end */
    execv(...);
}

请注意,如果管道的数组索引用于 stdio 重定向,则它们的选择方式会反射(reflect)标准输入/输出文件描述符。这个选择不是随意的。

当然,你可以将管道连接到任何文件描述符(例如,有一些应用程序希望它们的父级打开,比如 fd 3 和 4,连接到管道)并且大多数 shell 也直接支持这一点(例如 1> &3 会将 stdout 重定向到 fd 3)。然而,pipe(int fds[2]) 的数组索引当然是 0 和 1。我之所以这么说,是因为我有一些 cargo-cult-programming 学生,他们盲目地将目标 fds 也用于管道系统调用数组。

等待所有子进程完成使用 waitpid(-1, NULL, 0) – 我认为这是我的预回答者的意思,这意味着:WAITING所有子进程结束。另一种选择是在循环中调用 wait(),这将返回刚刚终止的子进程的 pid。如果再次调用,还有一个 child 在跑,它会再次阻塞。如果没有 child ,它将返回-1;我更喜欢 waitpid 解决方案。

关于c - 是否可以在同一父进程(LINUX、POSIX)创建的两个子进程之间建立管道,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5225810/

相关文章:

c - 如果线程在释放内存之前被杀死,如何释放线程分配的内存?

c - K&R C 书关于 scanf 如何处理格式字符串中的空格和制表符的问题?

linux - 在 makefile 中设置共享库的路径以进行编译

c - 等待无法同步三个进程

c - 动态内存分配问题

php exec() 不适用于 PredictionIO 部署

linux - 不断收到错误 : ModuleNotFoundError: No module named 'piecash'

java - 如何决定在套接字通信中使用哪个端口

c++ - Unix 用户空间中的实时 IPC

c - 为什么在管道的读取端关闭时不会发生 SIGPIPE?