Questions about Systm calls are called fork () and pipe () in C

   #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],&result,sizeof(result)<0)){
                   perror("5");
                   return 1;
               }
               result++;
               output = p[n][1];
               if(write(output,&result,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],&result,sizeof(result))<0){
                   perror("10");
                   return 1;
               }
               result++;
               output = p[i][1];
               if(write(output,&result,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],&result,sizeof(result))<0){
               perror("15");
               return 1;
           }
           printf("Result: %d\n",result);
           if(close(p[n][0])<0){
               perror("16");
               return 1;
           }
       }
       return 0;
   }

The program aims to read the number n from the command line, and then translates the n child process and creates n channels. process p0will be the parent of the process p1, p1will be the parent p2, and so on. One variable (named result here) will be passed through the channels, each time it is passed, it will be added 1. Thus, the output must also be n. The pipe Ficonnects Piand P(i+1). Attached is my code.

n = 1 n = 2, , 1 2 . , n = 3, 5. , , . - ? !

+4
1

n = 3, 5.

, if(close(p[i][1]<0)){ , p[i][0] , ..

if (i == n) {
    if(read(p[n-1][0],&result,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 N\n", 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 %d\n", getpid(), val);

            val++;
        }
        else {
            close(pipes[i][0]);

            printf("P %d writes %d\n", getpid(), val);

            if (write(pipes[i][1], &val, 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.

:

for (i = 0; i < n; i++) { pipe(); fork(); }, , n n . pipes[i][1], child pipes[i][0]. , , , .

+1

Source: https://habr.com/ru/post/1532613/


All Articles