Search code examples
cprocesspipeforkipc

Two processes substracting a number using pipe


Having difficulty to make two processes comunicate through pipe and substract a number alternatively.

Output should be like: process1: 9 process2: 8 process1: 7...

What I've did so far:

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

int main() {
    int p2c[2];
    int c2p[2];
    int n = 9;

    pipe(p2c);
    pipe(c2p);

    write(p2c[1], &n, sizeof(int));

    if(fork() == 0) {
        read(p2c[0], &n, sizeof(int));
        printf("Got from parent: %d", n);
    n--;
    write(c2p[1], &n, sizeof(int));
    close(p2c[0]);
    close(p2c[1]);
    close(c2p[0]);
    close(c2p[1]);
    exit(0);
}
else{
    read(c2p[0], &n, sizeof(int));
    printf("Got from child: %d", n);
    n--;
    write(p2c[1], &n; sizeof(int));
    close(p2c[0]);
    close(p2c[1]);
    close(c2p[0]);
    close(c2p[1]);

}
return 0;
}

Whith the output: Got from parent:9 Got from child:8 What's the proper way to get these two processes substract the number till 0?


Solution

  • It makes sense that you're only getting "Got from parent:9 Got from child:8" as a result, you need, you need a while or for loop for both child and parent processes to get what you're expecting, and the stop conditions for those loops are (n < 0) after decrementing n or the write end of pipe get closed:

    #include <stdio.h>
    #include <stdlib.h>
    #include <unistd.h>
    #include <sys/types.h>
    #include <sys/wait.h>
    
    int main() {
        int p2c[2];
        int c2p[2];
        int n = 9;
    
        pipe(p2c);
        pipe(c2p);
    
        // this is important to prevent deadlock situation, at least one of both processes
        // must start a write operation before while loop, unless the read will block and 
        // and each process still waiting the other to write something on the pipe
        write(p2c[1], &n, sizeof(int));
    
        if(fork() == 0) {
            int readStatus;
            while(1){
                readStatus=read(p2c[0], &n, sizeof(int));
                // when read returns 0, this means the write end of pipe was closed, so we have to break the loop
                // because no more data to recieve
                if(readStatus == 0) break;
                printf("Got from parent: %d\n", n);
                n--;
                // we check if n less than 0, if yes we are finished
                if(n < 0) break;
                write(c2p[1], &n, sizeof(int));
            }
            close(p2c[0]);
            close(p2c[1]);
            close(c2p[0]);
            close(c2p[1]);
            exit(0);
        }
        else{
            int readStatus;
            while(1){
                readStatus= read(c2p[0], &n, sizeof(int));
                if(readStatus == 0) break;
                printf("Got from child: %d\n", n);
                n--;
                if(n < 0) break;
                write(p2c[1], &n, sizeof(int));   
            } 
    
            close(p2c[0]);
            close(p2c[1]);
            close(c2p[0]);
            close(c2p[1]);
    
        }
        return 0;
    }