unix - 为什么我不能重用管道与多个子进程通信?
问题描述
如果我有一个包含子进程的父进程n
,为什么我不能使用一个管道将父进程的 pid 发送到所有子进程?这篇文章对此进行了简要介绍,但我觉得解释得不够清楚。
这是我的代码:
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
void main(void){
int n;
printf("How many child processes would you like to create?");
scanf("%d", &n);
pid_t pid, child, ppid, pidout;
int fd[2];
pipe(fd);
for (int i = 0; i < n; i++){
pid = fork();
switch(pid){
case -1:
printf("error forking at index %i", i);
exit(1);
case 0:
close(fd[1]);
child = getpid();
read(fd[0], &pidout, 4);
printf("\nNode : %i\nMy pid is : %i\nMy parent's pid is : %i\n\n", i, child, pidout);
exit(0);
default:
close(fd[0]);
ppid = getpid();
write(fd[1], &ppid, 4);
if (!i){
printf("\nNode : %i, My pid is : %i\n\n", i, ppid);
}
}
}
for (int i = 0; i < n; i++){
wait();
}
}
在这里,我尝试重用相同的管道将数据从父级发送到子级,但是在父级的 pid 发送到第一个子级后,管道会中断。我知道解决这个问题的方法是使用n-1
管道:每个通信一个。但是,我不明白为什么这段代码不起作用。任何澄清将不胜感激。谢谢!
解决方案
(警告:我不是管道和 Unix IPC 专家。)
您可能看到的是管道的预期行为,即通过管道的东西从另一边出来,而不仅仅是留在那里供其他人观察。一个进程写入,另一个进程读取 - 管道不会保留所有数据,并且会被清除。
也许一个不同的系统调用可以工作,它允许在管道缓冲区达到峰值而不清除它,尽管这听起来不是一个优雅的解决方案。另一种可能的方法是建立一个进程间共享内存区域形式的“海报板”,父进程可以写入该内存区域,子进程可以读取该区域。
编辑:在创建所有子项之前,您还存在过早关闭管道读取端的问题。请参阅@MarcoLucidi 的回答。
推荐阅读
- python - Removing the break line of words form texts that are on a list
- numpy - 如何表示负 X 轴上的信号
- vue.js - How can I import an other custom component using Vue composition API?
- javascript - Making a visible submenu in the menu with scroll overflow
- python - What are the numpy array formats, dtypes?
- xml - What do '|', '?', '+', '*', and ',' mean in a DTD file?
- python - 使用递归/获取“无”附加到我的输出
- python - 如何在 python 中使用 *args 进行划分?
- flutter - Flutter 需要两次点击/点击来改变 `ontap` 颜色变化
- python - 如何过滤数据框行并将总和保存在新行中?