gpt4 book ai didi

c - 使用 fork() 和管道的进程环

转载 作者:太空狗 更新时间:2023-10-29 12:16:33 27 4
gpt4 key购买 nike

一个小时以来,我一直在为这个问题绞尽脑汁。我必须创建一个包含 n 个进程的进程环(数量通过 cmd 作为参数传递)。父进程将他的 PID 发送给他的第一个 child ,而这个进程将他 parent 的 PID 加上他自己的 PID 发送给他的下一个兄弟,直到我们创建了 n 个 child 。之后,父进程得到他所有子进程的PID。

假设父进程的 PID 为 3400,我们创建了两个子进程,因此环由三个进程组成

3400 + 3401(第一个 child 的 PID)+ 3402(第二个 child 的 PID)= 10203

父进程应该得到这个 10203。

我考虑过一个“for”循环,其中子进程仅使用一个管道将其兄弟 PID 的添加从兄弟发送到兄弟。尽管如此,我还没有找到解决方案。

最佳答案

鉴于任务是使用 fork()pipe(),您可能需要使用如下算法:

  • parent 为其创建管道以写入第一个st child 。
  • Parent 保持打开管道的写端给第一个st child。
  • 父级保持打开来自第 N 个子级的管道的读取端。
  • 对于每个子节点 n = 1..N,父节点为第 n 个子节点创建输出管道以与第 n+1 对话。
  • parent fork 了第 n 个 child 。
  • 第 n 个 child 关闭其输入管道的写入端和其输出管道的读取端。
  • nth 个 child 从输入管道读取 PID 的总和,将自己的 pid 添加到总和,并将其写入输出管道,然后退出。
  • 与此同时,Parent 将输入管道的两端关闭到第 nth(除了必须保持打开的描述符),然后循环返回以创建第 n+1 sup> child 的 pipe ,然后是 child 。
  • 当所有的 child 都启动后, parent 将其 PID 写入第一个st child 并关闭该管道的写入端。
  • 然后它从第 Nth 个 child 读取响应,关闭管道的读取端,并打印结果。

除非每个 child 也将其 PID 写入标准输出,或者 parent (知道所有 child 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

fflush(stdout); 的目的在以下情况下变得清晰:(a) 您省略它并且 (b) 您通过管道运行输出。这是必要的。

关于c - 使用 fork() 和管道的进程环,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22792300/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com