我在一小时内就这个问题一直在震撼我的大脑。我必须用n个进程创建一个进程环(数量通过cmd作为参数传递)。父进程将他的PID发送给他的第一个孩子,这个将父亲的PID和他自己的PID发送给他的下一个兄弟,直到我们创建了n个孩子。之后,父进程将获得他所有孩子的PID。
假设父进程'PID为3400,我们创建了两个子进程,因此环由三个进程组成
3400 + 3401(第一个孩子的PID)+ 3402(第二个孩子的PID)= 10203
父进程应该得到10203。
我想过一个“for”循环,其中子进程只使用一个管道从兄弟到兄弟发送兄弟PID的添加。尽管如此,我还没有找到解决方案。
答案 0 :(得分:2)
鉴于任务是使用fork()
和pipe()
,您可能需要使用以下算法:
除非每个孩子也将其PID写入标准输出,或者父母(知道所有子PID)计算验证它的答案,否则验证总和的方法不太明显。
由于完全没有错误检查而没有标记:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
int main(int argc, char **argv)
{
int N = (argc > 1) ? atoi(argv[1]) : 10;
int c1_wr;
int cN_rd;
int p1[2];
int p2[2];
int pid_chk = getpid();
if (N <= 0 || N >= 100)
N = 10;
pipe(p1);
c1_wr = dup(p1[1]);
printf("%d children\n", N);
printf("Parent = %d\n", pid_chk);
for (int n = 0; n < N; n++)
{
int pid;
pipe(p2);
fflush(stdout);
if ((pid = fork()) == 0)
{
close(p1[1]);
close(p2[0]);
int pid_sum;
read(p1[0], &pid_sum, sizeof(pid_sum));
pid_sum += getpid();
write(p2[1], &pid_sum, sizeof(pid_sum));
close(p1[0]);
close(p2[1]);
exit(0);
}
printf("Child %2d = %d\n", n+1, pid);
pid_chk += pid;
close(p1[0]);
close(p1[1]);
p1[0] = p2[0];
p1[1] = p2[1];
}
cN_rd = p2[0];
close(p2[1]);
int pid_sum = getpid();
write(c1_wr, &pid_sum, sizeof(pid_sum));
close(c1_wr);
read(cN_rd, &pid_sum, sizeof(pid_sum));
close(cN_rd);
printf("PID sum = %d\n", pid_sum);
printf("PID chk = %d\n", pid_chk);
return 0;
}
示例运行:
10 children
Parent = 49686
Child 1 = 49688
Child 2 = 49689
Child 3 = 49690
Child 4 = 49691
Child 5 = 49692
Child 6 = 49693
Child 7 = 49694
Child 8 = 49695
Child 9 = 49696
Child 10 = 49697
PID sum = 546611
PID chk = 546611
如果(a)省略它并且(b)通过管道运行输出,则fflush(stdout);
的目的变得清晰。这是必要的。
答案 1 :(得分:0)
答案 2 :(得分:0)
如果您控制子进程的行为,并且父进程在启动子进程之前没有重要/难以重新创建的状态,则可以简化操作。
您可以让父级递归启动已分离的子项,终止自身,让最后一个子项重新启动父项,而不是IPC;
parent n
,其中n
是要生成的子项数。parent
:
child arg1-1 0
并终止,"0"
调用arg1
,它会将自己的PID添加到arg2
并且您已完成,即使在进程树方面它不是真正的“父”什么。child
:
child arg-1 arg2+pid
,其中pid
是孩子自己的PID。 "0"
调用了arg1
,则会调用parent 0 arg2+pid
。