加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

关于Systm的问题在C中调用fork()和pipe()

发布时间:2020-12-16 07:08:13 所属栏目:百科 来源:网络整理
导读:#includestdio.h #includestdlib.h #includeunistd.h #includesys/wait.h #includeerrno.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)
#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时给出了错误的文件错误.我已经整个下午手动跟踪代码,但不知道它有什么问题.有人可以帮忙吗?首先欣赏它!

解决方法

when n=3,it gives me a bad file error at error 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]读取.最终,它将创建一个由一系列管道连接的流程链,并通过该系列管道将值从第一个流程传递到最后一个流程.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读