Search code examples
clinuxprocesspipefork

How to send multiple strings from parent to child processes trough pipe?


I'm trying to write a C code by creating a parent process with 3 child processes, where the parent sends five lines of a file trough a pipe and all the 3 child processes print the received strings on the screen.
I know there are several questions about this topic, but I couldn't manage to solve my problem looking there for solutions.
My problem is that only the first child receives the strings, prints them and then the program stops.
Here is the code:

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

#define MAX_CHILDREN 3

int main( void )
{
    pid_t pid;

    int fd[2];
    FILE *f;


    int num_process;
    for(num_process = 0; num_process < MAX_CHILDREN; num_process++)
    {
        if(pipe(fd) == -1)
        {
            perror( "pipe Failed" );
            continue;
        }

        pid = fork();

        if(pid < 0)
        {
            perror("fork failed");
            exit(1);
        }

        if(pid == 0)
        { //child code
            char buff[256];

            printf("Child %i (pid= %i)\n", num_process, getpid());
            close(fd[1]);

            while(read( fd[0], buff, sizeof(buff))>0)
            {
            printf("Read child = %s\n", buff);
            }
            exit(0);

        }
       else{//parent
            printf("Im parent %i\n",getpid());
            close(fd[0]);

            int i;
            int str_len=256;
            char str[str_len];
            f=fopen("input.dat","r");

            for(i=0;i<5;i++)
            {
            fgets(str,str_len,f);
            write(fd[1], str,strlen(str));
            printf("Parent send %s\n", str);
            }

            wait(NULL);
        }
    }
    fclose(f);
    return 0;
}

The output I get looks like this:

Im parent 65090
Parent send apple

Parent send banana

Parent send cherry

Parent send cat

Parent send dog

Child 0 (pid= 65091)
Read child = apple
banana
cherry
cat
dog

Why does the program stop after the first child?


Solution

  • #include <stdio.h>
    #include <unistd.h>
    #include <sys/types.h>
    #include <stdlib.h>
    #include <string.h>
    #include <sys/wait.h>
    
    #define MAX_CHILDREN 3
    
    int main(void)
    {
      pid_t pid;
    
      int fd[2];
      FILE *f;
    
      int num_process;
      for (num_process = 0; num_process < MAX_CHILDREN; num_process++)
      {
        if (pipe(fd) == -1)
        {
          perror("pipe Failed");
          return 0;
        }
    
        pid = fork();
    
        if (pid < 0)
        {
          perror("fork failed");
          exit(1);
        }
    
        if (pid == 0)
        { //child code
          sleep(1); // for a nice output
          char buff[256];
    
          printf("Child %i (pid= %i)\n", num_process, getpid());
          close(fd[1]);
    
          while (read(fd[0], buff, sizeof(buff)) > 0)
          {
            printf("Read child = %s\n", buff);
          }
          close(fd[0]); // neccessary
          exit(0);
        }
        else{//parent
          printf("Im parent %i\n", getpid());
          close(fd[0]);
    
          int i;
          int str_len = 256;
          char str[str_len];
          f = fopen("input.dat", "r");
    
          for (i = 0; i < 5; i++)
          {
            fgets(str, str_len, f);
            close(fd[0]); // neccessary
            write(fd[1], str, strlen(str));
            printf("Parent send %s\n", str);
          }
          close(fd[1]); // neccessary
          wait(NULL);
        }
      }
      fclose(f);
      return 0;
    }
    

    You forgot to close the pipe array, where I wrote the comments: neccessary. That's why your program looks like stopped. I hope this help you a bit.

    Output:
    Im parent 398270
    Parent send apple
    
    Parent send bananana
    
    Parent send cherry
    
    Parent send cat
    
    Parent send dog
    
    Child 0 (pid= 398271)
    Read child = apple
    bananana
    cherry
    cat
    dog
    
    Im parent 398270
    Parent send apple
    
    Parent send bananana
    
    Parent send cherry
    
    Parent send cat
    
    Parent send dog
    
    Child 1 (pid= 398482)
    Read child = apple
    bananana
    cherry
    cat
    dog
    
    Im parent 398270
    Parent send apple
    
    Parent send bananana
    
    Parent send cherry
    
    Parent send cat
    
    Parent send dog
    
    Child 2 (pid= 398484)
    Read child = apple
    bananana
    cherry
    cat
    dog