Search code examples
cunixpipepipeline

Read/write value with pipe


I have a problem with this code, how i can send a number betwen this procces, like 1 send to 2, 2 send to 3, and 3 send to 1, and everytime decreases with an i*10, like first time 10, second time 20, ...30 , ... until the number is negative, and then stop the program? I make this code, but i have a problem, the value of number 'a', dont decrease like a=1342 in 1, decrease 20, and in 2 need to have 1322, it's start from 1342. Here is my code:

 #include <sys/types.h>
#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>

int i=0;
int main()
{
    pid_t p;
    int a=1324;
    int fd[2];
    int fd1[2];
    pipe(fd);
    p=fork():
    if(p < 0)
    {
        perror("Fork error");
        exit(1);
    }
    else if(p==0)
    {
    while(1)
    {
        close(fd1[1]);
        read(fd1[0],&a, sizeof(int));
        printf("Procces 2, a is %d.\n",a);
        wait(1);
        close(fd[0]);
        a=a-(i*10);
        i++;
        write(fd[1],&a,sizeof(int));
    }
    }
    else
    {
    p=fork();
    if(p < 0)
    {
        perror("Fork error");
        exit(1);
    }
    if(p > 0)
    {
        while(1)
        {
            close(fd1[1]);
            read(fd1[0],&a, sizeof(int));
            printf("Procces 1, a is %d.\n",a);
            wait(1);
            close(fd1[0]);
            a=a-(i*10);
            i++;
            write(fd1[1],&a,sizeof(int));
        }
    }
    else
    {
        while(1)
        {
            close(fd[1]);
            read(fd[0],&a, sizeof(int));
            printf("Procces 3, a is %d.\n",a);
            wait(1);
            close(fd1[0]);
            a=a-(i*10);
            i++;
            write(fd1[1],&a,sizeof(int));
        }
    }
}
return 1;

}

  • I want to print like this:
  • Process 1, a is 1324 (decrease 0 and send to 2)
  • Process 2, a is 1324 (decrease 10 and send to 3)
  • Process 3, a is 1314 (decrease 20 and send to 1)
  • Process 1, a is 1294 (decrease 30 and send to 2)
  • ...
  • But the program si some like this:
  • Process 1, a is 1324
  • Process 2, a is 1324
  • Process 3, a is 1324
  • Process 1, a is 1314
  • ...

Someone can tell me where is the problem? Thanks.


Solution

  • If this isn't what you're trying to do its damn close. You want to clearly identify which pipes are use for writing and reading for each process. The easiest way I've found to do that is by labeling the indexes with macros. For example. a sequence of six pipes (three pairs):

    //  This arrangement means;
    //
    //  P1 listens to P2, writes to P3
    //  P2 listens to P3, writes to P1
    //  P3 listens to P1, writes to P2
    
    #define P1_READ     0
    #define P2_WRITE    1
    #define P2_READ     2
    #define P3_WRITE    3
    #define P3_READ     4
    #define P1_WRITE    5
    #define NUM_PIPES   6
    

    This makes the client code substantially easier to understand:

    int main()
    {
        int a = 1324;
        int i=1;
    
        int fd[NUM_PIPES];
    
        // create pipes
        if (pipe(fd) < 0 || pipe(fd+2) < 0 || pipe(fd+4) < 0)
        {
            perror("Failed to create pipes");
            exit(EXIT_FAILURE);
        }
    
        // fork P2 child process
        if (fork() == 0)
        {
            close(fd[P1_READ]);
            close(fd[P1_WRITE]);
            close(fd[P3_READ]);
            close(fd[P3_WRITE]);
    
            while (read(fd[P2_READ], &a, sizeof(a)) == sizeof(a))
            {
                fprintf(stderr, "P2: (i==%d) received %d\n", i, a);
                if ((a -= (i++ * 10)) < 0)
                    break;
                write(fd[P2_WRITE], &a, sizeof(a));
            }
    
            // close our other pipes
            close(fd[P2_READ]);
            close(fd[P2_WRITE]);
            return EXIT_SUCCESS;
        }
        ////////////////////////////////////////////////////////////////
    
    
        // fork P3 child process
        if (fork() == 0)
        {
            close(fd[P1_READ]);
            close(fd[P1_WRITE]);
            close(fd[P2_READ]);
            close(fd[P2_WRITE]);
    
            while (read(fd[P3_READ], &a, sizeof(a)) == sizeof(a))
            {
                fprintf(stderr, "P3: (i==%d) received %d\n", i, a);
                if ((a -= (i++ * 10)) < 0)
                    break;
                write(fd[P3_WRITE], &a, sizeof(a));
            }
    
            // close our other pipes
            close(fd[P3_READ]);
            close(fd[P3_WRITE]);
            return EXIT_SUCCESS;
        }
        ////////////////////////////////////////////////////////////////
    
    
        // parent process. close the pipes we don't need
        close(fd[P2_READ]);
        close(fd[P2_WRITE]);
        close(fd[P3_READ]);
        close(fd[P3_WRITE]);
    
        // kick things off with a write of the first value
        write(fd[P1_WRITE], &a, sizeof(a));
    
        // same code as before
        while (read(fd[P1_READ], &a, sizeof(a)) == sizeof(a))
        {
            fprintf(stderr, "P1: (i==%d) received %d\n", i, a);
            if ((a -= (i++ * 10)) < 0)
                break;
            write(fd[P1_WRITE], &a, sizeof(a));
        }
    
        // close the pipes we no longer need
        close(fd[P1_READ]);
        close(fd[P1_WRITE]);
    
        wait(NULL);
    
        return EXIT_SUCCESS;
    }
    

    The resulting output looks something like this:

    P3: (i==1) received 1324
    P2: (i==1) received 1314
    P1: (i==1) received 1304
    P3: (i==2) received 1294
    P2: (i==2) received 1274
    P1: (i==2) received 1254
    P3: (i==3) received 1234
    P2: (i==3) received 1204
    P1: (i==3) received 1174
    P3: (i==4) received 1144
    P2: (i==4) received 1104
    P1: (i==4) received 1064
    P3: (i==5) received 1024
    P2: (i==5) received 974
    P1: (i==5) received 924
    P3: (i==6) received 874
    P2: (i==6) received 814
    P1: (i==6) received 754
    P3: (i==7) received 694
    P2: (i==7) received 624
    P1: (i==7) received 554
    P3: (i==8) received 484
    P2: (i==8) received 404
    P1: (i==8) received 324
    P3: (i==9) received 244
    P2: (i==9) received 154
    P1: (i==9) received 64
    

    Toy with the numbers (i, a,) to your leisure. Hope it helps.