关于Systm的问题在C中调用fork()和pipe()
#include<stdio.h> #include<stdlib.h> #include<unistd.h> #include<sys/wait.h> #include<errno.h> int main(int argc,char **argv){ int n = atoi(argv[1]); int superdaddy = getpid(); int p[n+1][2]; int i=0; int cpid,output; int result = 0; if(pipe(p[0])<0){ perror("1"); return 1; } if(pipe(p[n])<0){ perror("2"); return 1; } output = p[0][1]; if(getpid()==superdaddy){ if(write(p[0][1],&result,sizeof(result))<0){ perror("3"); return 1; } if(close(p[0][1])<0){ perror("4"); return 1; } } while(1){ if(i==n){ if(read(p[n-1][0],sizeof(result)<0)){ perror("5"); return 1; } result++; output = p[n][1]; if(write(output,sizeof(result))<0){ perror("6"); return 1; } if(close(p[n-1][0])<0){ perror("7"); return 1; } if(close(p[n][1])<0){ perror("8"); return 1; } break; } i++; cpid = fork(); if(cpid==0){ if(i==n) continue; if(pipe(p[i])<0){ perror("9"); return 1; } if(read(p[i-1][0],sizeof(result))<0){ perror("10"); return 1; } result++; output = p[i][1]; if(write(output,sizeof(result))<0){ perror("11"); return 1; } if(close(p[i-1][0])<0){ perror("12"); return 1; } if(close(p[i][1]<0)){ perror("13"); return 1; } continue; } else if(cpid<0){ perror("14"); return 1; } break; } if(getpid()==superdaddy){ wait(NULL); if(read(p[n][0],sizeof(result))<0){ perror("15"); return 1; } printf("Result: %dn",result); if(close(p[n][0])<0){ perror("16"); return 1; } } return 0; } 该程序旨在从命令行读取数字n,然后分叉子进程并创建n个管道.进程p0将是进程p1的父进程,p1将成为p2的父进程,依此类推.一个变量(在这里命名为result)将通过管道传递,每次传递时它都将被添加1.因此输出也应该是n. Pipe Fi连接Pi和P(i 1).附上是我的代码. 当n = 1或n = 2时,程序可以正确输出,相应地为1和2.但是,当n = 3时,它在错误5时给出了错误的文件错误.我已经整个下午手动跟踪代码,但不知道它有什么问题.有人可以帮忙吗?首先欣赏它! 解决方法
这可以通过删除你的代码中的if(close(p [i] [1]< 0)){来修复,因为你需要在上一次迭代中从p [i] [0]读取,即 if (i == n) { if(read(p[n-1][0],sizeof(result)<0)){ ... } } 这是您的想法的实现,我希望它可能会有所帮助: #include <sys/types.h> #include <sys/wait.h> #include <stdio.h> #include <stdlib.h> #include <unistd.h> int main(int argc,char *argv[]) { if (argc != 2) { fprintf(stderr,"Usage: %s Nn",argv[0]); exit(EXIT_FAILURE); } int n = atoi(argv[1]); int pipes[n][2]; int i,val; pid_t pid; val = 0; for (i = 0; i < n; i++) { if (pipe(pipes[i]) < 0) { perror("pipe"); exit(EXIT_FAILURE); } if ((pid = fork()) < 0) { perror("fork"); exit(EXIT_FAILURE); } else if (pid == 0) { close(pipes[i][1]); if (read(pipes[i][0],&val,sizeof(val)) != sizeof(val)) { perror("read"); exit(EXIT_FAILURE); } printf("C %d read %dn",getpid(),val); val++; } else { close(pipes[i][0]); printf("P %d writes %dn",val); if (write(pipes[i][1],sizeof(val)) != sizeof(val)) { perror("write"); exit(EXIT_FAILURE); } if (waitpid(pid,NULL,0) != pid) { perror("waitpid"); exit(EXIT_FAILURE); } printf("%d is going to leave.n",getpid()); exit(EXIT_SUCCESS); } } printf("%d is going to leave.n",getpid()); exit(EXIT_SUCCESS); } 测试运行: $./a.out 3 P 2005 writes 0 C 2006 read 0 P 2006 writes 1 C 2007 read 1 P 2007 writes 2 C 2008 read 2 2008 is going to leave. 2007 is going to leave. 2006 is going to leave. 2005 is going to leave. 说明: 该代码的帧是(i = 0; i< n; i){pipe();叉子(); },这意味着它将创建n个管道和n个新进程.在每次迭代中,父级将写入管道[i] [1],子级将从管道[i] [0]读取.最终,它将创建一个由一系列管道连接的流程链,并通过该系列管道将值从第一个流程传递到最后一个流程. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |