Anis Nouri
Anis Nouri

Reputation: 21

Communication between processes with pipes

I'm trying to implement a program which take a sequence of parameter in the input and depending in that it create an equal number of processes implemented by pipes ,where each process write in the pipe and then pass it to the father .

here is my code ,it doesn't do what i need .

thank you for help .

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



int main(int argc ,char *argv[])
{
 int i,pid;
 int fd[2];//crea i descriptor 
 char phrase[30][30];//crea il buffer
 pipe(fd); /* crea la pipe */

     // Genera i 10 processi
  for(i=0;i<argc-1;i++)
  {
   if((pid=fork())==0)
    {               
      strcpy(phrase[i], argv[i+1]);  
      printf("ho scritoo :'%s'\n",*phrase);
      close(fd[0]);                         /* chiude in lettura */
      write(fd[1],phrase,strlen(*phrase)+1); /* invia anche 0x00 */
      close (fd[1]);                   // chiude in scrittura
                                // pid=0 -> figlio
      usleep(50000*(1+i));      // Ritardo iniziale
      printf("Figlio: %d\n",i+1);   // Stampa messaggio del figlio
      usleep(500000*(1+i));     // Ritardo finale
      return(101+i);            // Termina con codice di ritorno
       } 
   else { 
        printf("Ho generato il figlio %d con pid %d\n",i+1,pid);
        char message[100];    //creare il buffer 
        memset(message,0,100);
        int bytesread;  
        close(fd[1]);                         /* chiude in scrittura */
        bytesread = read(fd[0],message,sizeof(message));
        printf("ho letto dalla pipe %d bytes: '%s' \n",bytesread,message);
        close(fd[0]);
    }
  }

  // Attende che dieci processi terminino
  for(i=0;i<argc-1;i++)
  {
    int status;
    wait(&status);      // Attende termine di un figlio (uno qualunque)
    printf("Terminato processo %d\n",WEXITSTATUS(status));
  }
}

Input : ./pipes cmd1 cmd2 cmd3

 I created the first child with pid 21552
 I wrote: 'cmd1'
 I read from the pipe 5 bytes: 'cmd1'
 I created the second child with pid 21553
 I read from the pipe -1 bytes:''
 I wrote: ') ML?'
 I created the third child with pid 21554
 I read from the pipe -1 bytes:''
 I write: ') ML?'
 Son: 1
 Son: 2
 Son: 3
 Ended process 101
 Ended process 102
 Ended process 103

Upvotes: 2

Views: 1649

Answers (1)

Bechir
Bechir

Reputation: 1051

You have two issues:

First, you are not writing the right phrase to the pipe. You are writing phrase all the time. For the first child, this is OK, for others, it will be empty string.

Second, you are closing fd[0] after creating the first child. You will never received data from other process.

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

int main(int argc ,char *argv[])
{
    int i,pid;
    int fd[2];//crea i descriptor 
    char phrase[30][30];//crea il buffer
    pipe(fd); /* crea la pipe */

    for(i = 0; i < argc - 1 ; i++)
    {
        if((pid=fork())==0)
        {               
            strcpy(phrase[i], argv[i+1]);  
            printf("ho scritoo :'%s'\n",phrase);
            close(fd[0]);                         /* chiude in lettura */
            write(fd[1],phrase[i],strlen(phrase[i])+1); /* invia anche 0x00 */
            close (fd[1]);                   // chiude in scrittura
            // pid=0 -> figlio
            usleep(50000*(1+i));      // Ritardo iniziale
            printf("Figlio: %d\n",i+1);   // Stampa messaggio del figlio
            usleep(500000*(1+i));     // Ritardo finale
            return(101+i);            // Termina con codice di ritorno
        } else { 
            printf("Ho generato il figlio %d con pid %d\n",i+1,pid);
            char message[100];    //creare il buffer 
            memset(message,0,100);
            int bytesread;  

            bytesread = read(fd[0],message,sizeof(message));
            printf("ho letto dalla pipe %d bytes: '%s' \n",bytesread,message);
            // close(fd[0]);
        }
    }
    close(fd[0]);                         /* chiude in scrittura */
    close(fd[1]);                         /* chiude in scrittura */
    // Attende che dieci processi terminino
    for(i=0;i<argc-1;i++)
    {
        int status;
        wait(&status);      // Attende termine di un figlio (uno qualunque)
        printf("Terminato processo %d\n",WEXITSTATUS(status));
    }
    return 0;
}

Upvotes: 2

Related Questions