Thread: Iterative Fork() and Pipes in C

  1. #1
    Registered User
    Join Date
    Oct 2011
    Posts
    2

    Iterative Fork() and Pipes in C

    Hello all,

    Hope you are all doing well.

    I am very new to c programming and I have a task where I must make three (or more forks) communicate with the process that created them.

    I used a for loop to create the forks, which did fine.
    However, when trying to communicate, I used pipes (on the basis of FIFO), but I am not getting the output I need.

    Let me explain:
    The father must send to his sons their pids. (That is the son's pids).
    He successfully sends it to the first son, but however, he sends the first son pid to the second son. And finally send the second son pid to the third one. Which is wrong.

    What I want is that, the father sends to his sons their correct pids.

    Here is the code and below is my output.
    Can anyone help me please ?

    Code:
    #include <stdio.h>
    #include <stdlib.h>
    #include <unistd.h>
    #include <string.h>
    
    #define reading 0
    #define writing 1
    
    main()
    {
        int num_son,n;
        int *status;
        char c;
    
        //pipes declaration
        int pipe_father_son[2],pipe_son_father[2];
        
        printf("Father: I am the father and my pid is %d \n", getpid());
        
        //pipes initialisation
        pipe(pipe_son_father);
        pipe(pipe_father_son);
    
        int i;
        for(i=0; i<3; i++)
        {
            num_son=fork();
            if(num_son==-1)
            {
                printf("creation error \n");
                exit(1);
            }
            if(num_son!=0)    //father process
            {
                char message[15];
                int n,num;
    
                //the father send the son his number
                num = num_son;
    
                //close the pipe on read to write in it            
                close(pipe_father_son[reading]);
                n=write(pipe_father_son[writing],&num,sizeof(num));
    
                //the father receives a message from his son
                ////close the pipe on write to read in it
                close(pipe_son_father[writing]);
                n=read(pipe_son_father[reading],&message,sizeof(message));
                //printf("Father: i received %s\n",message);
    
                //the father replies to his son
                strcpy(message,"you are welcome");
                n=write(pipe_father_son[writing],&message,sizeof(message));
    
                //closes the pipes
                close(pipe_father_son[writing]);
                close(pipe_son_father[reading]);
                
                sleep(1);
    
            }
            else    //son process
            {
                int num_process,num_process_father,num;
                char message[15];
    
                num_process=getpid();
                num_process_father=getppid();
    
                //the son receives his number from his father
                close(pipe_father_son[writing]);
                n=read(pipe_father_son[reading],&num,sizeof(num));
                printf("Son: %d my pid is %d and i received %d from my father %d \n",i,num_process,num,getppid());
    
                //the son thanks his father
                close(pipe_son_father[reading]);
                strcpy(message,"thanks");
                n=write(pipe_son_father[writing],&message,sizeof(message));
    
                //the son receives the you are welcome message from his father
                n=read(pipe_father_son[reading],&message,sizeof(message));
                //printf("Son: I received %s\n",message);
    
                //closes the pipes
                close(pipe_father_son[reading]);
                close(pipe_son_father[writing]);
                
                sleep(1);
                exit(num_son);
                
            }
            
    
        }
    
        for(i=0; i<3; i++)
        {
            wait(&status);
            printf("Father: my son %d is over\n",i,(int) status/256);
            sleep(1);
        }
    }
    Father: I am the father and my pid is 1804
    Son: 0 my pid is 1805 and i received 1805 from my father 1804
    Son: 1 my pid is 1806 and i received 1805 from my father 1804
    Son: 2 my pid is 1807 and i received 1806 from my father 1804
    Father: my son 0 is over
    Father: my son 1 is over
    Father: my son 2 is overpost.c

  2. #2
    Registered User
    Join Date
    Sep 2007
    Posts
    1,012
    First, you should #include <sys/types.h> and <sys/wait.h> for wait(), and then change status from an int* to an int. If you're using gcc, always build with the -Wall option, which will help catch such problems (there are more warnings it will yield that you should heed).

    Here's a hint to help you figure out the problem: check the return value of your write() and read() calls.

  3. #3
    Registered User
    Join Date
    Oct 2008
    Location
    TX
    Posts
    2,059
    I'd suggest you read up on *nix pipes before attempting this. For starters the parent is forking three child processes, yet you are closing the file descriptors which are shared among them. And, you don't need 4 pipe file descriptors, create one to be shared by all three children plus the one parent.
    Code:
    #include <stdio.h>
    #include <stdlib.h>
    #include <unistd.h>
    #include <string.h>
    
    #define reading 0
    #define writing 1
    
    main()
    {
        int num_son,n;
        int *status;
        char c;
    
        /* don't need 4 file descriptors */
        int pipe_father_son[2],pipe_son_father[2];
        
        printf("Father: I am the father and my pid is %d \n", getpid());
        
        /* single pipe() call is enough as file descriptors will be shared by all */
        pipe(pipe_son_father);
        pipe(pipe_father_son);
    
        int i;
        for(i=0; i<3; i++)
        {
            num_son=fork();
            if(num_son==-1)
            {
                printf("creation error \n");
                exit(1);
            }
            if(num_son!=0)    //father process
            {
                char message[15];
                int n,num;
    
                //the father send the son his number
                num = num_son;
    
                /* Remove all close() calls as file descriptors are shared by all processes i.e. 1 parent + 3 children */
                close(pipe_father_son[reading]);
                n=write(pipe_father_son[writing],&num,sizeof(num));
    
                //the father receives a message from his son
                ////close the pipe on write to read in it
                close(pipe_son_father[writing]);   
                n=read(pipe_son_father[reading],&message,sizeof(message));
                //printf("Father: i received %s\n",message);
    
                //the father replies to his son
                strcpy(message,"you are welcome");
                n=write(pipe_father_son[writing],&message,sizeof(message));
    
                //closes the pipes
                close(pipe_father_son[writing]);
                close(pipe_son_father[reading]);
                
                sleep(1);
    
            }
            else    //son process
            {
                int num_process,num_process_father,num;
                char message[15];
    
                num_process=getpid();
                num_process_father=getppid();
    
                //the son receives his number from his father
                close(pipe_father_son[writing]);
                n=read(pipe_father_son[reading],&num,sizeof(num));
                printf("Son: %d my pid is %d and i received %d from my father %d \n",i,num_process,num,getppid());
    
                //the son thanks his father
                close(pipe_son_father[reading]);
                strcpy(message,"thanks");
                n=write(pipe_son_father[writing],&message,sizeof(message));
    
                //the son receives the you are welcome message from his father
                n=read(pipe_father_son[reading],&message,sizeof(message));
                //printf("Son: I received %s\n",message);
    
                //closes the pipes
                close(pipe_father_son[reading]);
                close(pipe_son_father[writing]);
                
                sleep(1);
                exit(num_son);
                
            }
            
    
        }
    
        for(i=0; i<3; i++)
        {
            wait(&status);
            printf("Father: my son %d is over\n",i,(int) status/256);
            sleep(1);
        }
    }
    Last edited by itCbitC; 10-04-2011 at 08:40 AM.

  4. #4
    Registered User
    Join Date
    Oct 2011
    Posts
    2
    thanks guys !
    I'll try your suggestions soon as soon as possible and will reply.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. help with pipes/fork
    By omega666 in forum C Programming
    Replies: 2
    Last Post: 03-14-2011, 06:58 PM
  2. Replies: 3
    Last Post: 06-02-2009, 06:13 PM
  3. Iterative functions
    By russel1013 in forum C Programming
    Replies: 7
    Last Post: 07-21-2008, 03:14 AM
  4. iterative combinations
    By antreas_z in forum C++ Programming
    Replies: 3
    Last Post: 06-02-2003, 06:39 AM

Tags for this Thread