Linux pass value between parent process and child

2019-04-15 05:40发布

问题:

A Process creates a child process, increase x by 1, then send x value to the child process, the child process can then multiply x by 10, and pass x back to the parent process and so on. You should at least do this 5 times.

the output should look like this:

initial value 0

Parent:

x value after operation:1

Child:

x value after operation:10

Parent:

x value after operation:11

Child:

x value after operation:110

Parent:

x value after operation:111

Child

x value after operation:1110

What i have is the following.......

#include <sys/types.h>
#include <stdio.h>
#include <unistd.h>
#include <sys/syscall.h>

#define READ 0
#define WRITE 1

int main()
{
  pid_t pid;
  int mypipefd[2];
  int ret;
  int i;
  int x=0;
  int result,result2;

  ret = pipe(mypipefd);

  if(ret ==-1)                    //test for pipe
    {
      perror("pipe");             //show error and exit  
      exit(1);
    }

  printf("initial value %d\n", x);   

  pid = fork();

  for(i=0;i<5;i++)

{

  if(pid == 0)
    {
        /*Child process*/

  result2=result*10;
  write(mypipefd[WRITE],&result2,sizeof(result2));
  printf("Child:\nx value after operation: %d\n", x);
  close(mypipefd[WRITE]);
  read(mypipefd[READ],&result2,sizeof(result2));

  printf("=======================================\n");
  close(mypipefd[READ]);

}

  else if(pid > 0) 
{
   /*Parent process*/

 result=x++;
 write(mypipefd[READ],&result,sizeof(result));   
 printf("Parent:\nx value after operation: %d\n", x); 
 close(mypipefd[WRITE]);
 read(mypipefd[WRITE],&result,sizeof(result)); 

 printf("=======================================\n");
 close(mypipefd[READ]);
 exit(0);

}

 else
{
  perror("fork");
  exit(1);
    }

  }

}

The question is, what's wrong with my code? I tried to READ and WRITE back the the pipe but seems not working...

What's the output of my code right now:

initial value 0

Parent:

x value after operation:1

Child:

x value after operation:0

Child:

x value after operation:0

Child:

x value after operation:0

Child:

x value after operation:0

Child:

x value after operation:0

回答1:

I think the first issue to address is that you have both ends of the pipe open when you are trying to read/write data. If you are writing data to the pipe you would

close(fd[READ_END])
write(...)
close(fd[WRITE_END])

Second, pipes in unix are simplex. You seem to be trying to read and write from the pipe at the same time. If you want to do this you are going to have to open two pipes.

I modified your program to show you how to read from pipe and then write to pipe for parent/child. Hopefully this helps you.

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

#define BUFFER_SIZE 25
#define READ  0
#define WRITE 1

int main(void)
{
  pid_t pid;
  //open two pipes, one for each direction
  int mypipefd[2];
  int mypipefd2[2];

  /* create the pipe */
  if (pipe(mypipefd) == -1 || pipe(mypipefd2) == -1) {
    fprintf(stderr,"Pipe failed");
    return 1;
  }

  /* now fork a child process */
  pid = fork();

  if (pid < 0) {
    fprintf(stderr, "Fork failed");
    return 1;
  }

  if (pid > 0) {  /* parent process */  
    int writeValue=10;
    int readValue=0;
    close(mypipefd[READ]);      //close read end, write and then close write end
    write(mypipefd[WRITE],&writeValue,sizeof(writeValue));    //write to pipe one
    printf("Parent: writes value : %d\n", writeValue);
    close(mypipefd[WRITE]);
    close(mypipefd2[WRITE]);        //close write end, read, and then close read end
    read(mypipefd2[READ],&readValue,sizeof(readValue));
    printf("Parent: reads value : %d\n", readValue);
    close(mypipefd2[READ]);
  }
  else { /* child process */
    int writeValue=20;
    int readValue=0;
    close(mypipefd[WRITE]);   //close write end, read, and then close read end
    read(mypipefd[READ],&readValue,sizeof(readValue));
    printf("child: read value : %d\n", readValue);
    writeValue+=readValue;
    close(mypipefd[READ]);
    close(mypipefd2[READ]);       //close read end, write and then close write end
    write(mypipefd2[WRITE],&writeValue,sizeof(writeValue));
    printf("child: writeValue value : %d\n", writeValue);
    close(mypipefd2[WRITE]);

  }

  return 0;
}

This open two pipes. The parent writes a value to the first pipe and the child reads this value. The child updates this values, and writes it to the second direction pipe. The parent then reads this value and vuela! two way pipe communication.

Output:

Parent: writes value : 10
child: read value : 10
child: write value : 30
Parent: reads value : 30

This can be extended to your application as such

 if (pid > 0) {  /* parent process */  
    result1++;
    close(mypipefd[READ]);      //close read end, write and then close write end
    write(mypipefd[WRITE],&result1,sizeof(result1));    //write to pipe one
    printf("Parent:\n x value after operation: %d\n", result1);
    close(mypipefd[WRITE]);
    close(mypipefd2[WRITE]);        //close write end, read, and then close read end
    read(mypipefd2[READ],&result1,sizeof(result1));
    close(mypipefd2[READ]);
  }
  else { /* child process */
    close(mypipefd[WRITE]);   //close write end, read, and then close read end
    read(mypipefd[READ],&result2,sizeof(result2));
    result2*=10;
    printf("child:\n x value after operation %d\n", result2);
    close(mypipefd[READ]);
    close(mypipefd2[READ]);       //close read end, write and then close write end
    write(mypipefd2[WRITE],&result2,sizeof(result2));
    close(mypipefd2[WRITE]);
  }

If you put this in the loop then it would theoretically work. HOWEVER, The order of execution will be jumbled between the two processes due to context switching and other OS related scheduling. This means that reads and writes are not necessarily sequential the way you are doing it, And it wont work. Read into this question How to wait till data is written on the other end of pipe.



标签: c pipe