Home > Net >  Not understanding how the pipe works. (Shared memory between processes UNIX)
Not understanding how the pipe works. (Shared memory between processes UNIX)

Time:10-29

I am not understanding how the pipe works in UNIX, I did this code and I stumbled in a strange fact. The trace of the exercise can be found on the top of the code. Ill'explain what I can't get. In the father process when I want to print the values from the pipe, the value from where the "i" variable begins can be whatever number. I put "4" but it works for every number 2, 3 ,4 excetera. How can it work every time?

/*****************************************************************
    The candidate should complete the program provided, implementing
    the main.
    The program creates a child process; the child process reads
    from the keyboard an integer N >= 0, and transmits the values N, N-1, N-2, N-3, ..., 0
    (inclusive) to the parent process via a pipe.
    The father process reads from the pipe the values transmitted by the child process
    and prints them, until it receives the value 0; then the father process
    process waits for the termination of the child process and terminates.
    
    Example:
    I am the child process. Enter a number >=0: 4
    I am the father process. I have received: 4
    I am the father process. I have received: 3
    I am the father process. I have received: 2
    I am the father process. I have received: 1
    I am the father process. I have received: 0
    I am the father process. The son has finished.
    
******************************************************************/
    
    
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <unistd.h>
#include <sys/wait.h>
    
int main(int argc, char *argv[]) 
{
    
    int fd[2];
    int num, i;
    //Pipe creation
    if(pipe(fd)<0)
    {
        printf("Pipe creation failed\n");
        return 1;
    }
    //Creating a child process
    pid_t pid=fork();
    //Fork check
    if(pid<0)
    {
        printf("Fork failed\n");
        return 1;
    }
    //Entering the child process
    else if(pid==0){
        close (fd[0]);  // Not interested in reading
        printf("I am the child process\n");
        //Acquiring a number from input
        printf("Give me a number: ");
        scanf("%d", &num);
        //Sending the numbers trough a pipe
        for(i=num; i>=0; i--)
        {
            int sent=write(fd[1], &i, sizeof(num));
            //Check on the number of bytes the function wrote
            if(sent<0 || sent<sizeof(num))
            {
                printf("Error when sending\n");
                return 1;
            }
        }
        close (fd[1]);
        return 0;
    }
    //Entering the father process
    if(pid>0)
    {
        //Father process
        wait(NULL);
        close (fd[1]);// Not interested in writing
        for(i=4;i>=0;i--)//4 is a random number and it still works
        {
            int ricevuti=read(fd[0], &i, sizeof(num));
            //Check on the number of bytes the function read
            if(ricevuti<0 || ricevuti<(sizeof(num)))
            {
                printf("Error when receiving\n");
                return 1;
            }
            //Printing the values read by the function
            else
            {
                printf("I am the father process and i received: %d\n", i);
            }
        }
        printf("The child process has terminated\n");
    }
    close (fd[0]);
    return 0;
}

CodePudding user response:

The reason it works for any number is because you're reading from the pipe into the iteration variable used by the for loop. So even though you started it at i = 4, the first read(fd[0], &i, sizeof(num)) will change i to the starting number that the child sent.

You should be reading into num, not i. The father code should be:

    //Entering the father process
    if(pid>0)
    {
        //Father process
        wait(NULL);
        close (fd[1]);// Not interested in writing
        for(i=4;i>=0;i--)//4 is a random number and it still works
        {
            int ricevuti=read(fd[0], &num, sizeof(num));
            //Check on the number of bytes the function read
            if(ricevuti<0 || ricevuti<(sizeof(num)))
            {
                printf("Error when receiving\n");
                return 1;
            }
            //Printing the values read by the function
            else
            {
                printf("I am the father process and i received: %d\n", num);
            }
        }
        printf("The child process has terminated\n");
    }
  • Related