Linux在父进程和子进程之间使用c中的管道传递值?

use*_*620 1 c pipe

A Process 创建一个子进程,将 x 加 1,然后将 x 值发送给子进程,然后子进程可以将 x 乘以 10,并将 x 传递回父进程等等。你至少应该这样做5次。

输出应如下所示:

初始值 0

家长:

操作后的 x 值:1

孩子:

操作后的 x 值:10

家长:

操作后的 x 值:11

孩子:

操作后的 x 值:110

家长:

操作后的 x 值:111

孩子

操作后的 x 值:1110

我所拥有的是以下......

#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);
    }

  }

}
Run Code Online (Sandbox Code Playgroud)

问题是,我的代码有什么问题?我试图读取和写入管道,但似乎不起作用......

我的代码现在的输出是什么:

初始值 0

家长:

操作后的 x 值:1

孩子:

操作后的 x 值:0

孩子:

操作后的 x 值:0

孩子:

操作后的 x 值:0

孩子:

操作后的 x 值:0

孩子:

操作后的 x 值:0

Pan*_*aid 5

我认为要解决的第一个问题是,当您尝试读/写数据时,管道的两端都打开了。如果您将数据写入管道,您会

close(fd[READ_END])
write(...)
close(fd[WRITE_END])
Run Code Online (Sandbox Code Playgroud)

其次,unix 中的管道是单工的。您似乎正在尝试同时从管道中读取和写入。如果你想这样做,你将不得不打开两个管道。

我修改了您的程序以向您展示如何从管道读取,然后为父/子写入管道。希望这对你有帮助。

#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;
}
Run Code Online (Sandbox Code Playgroud)

这打开了两个管道。父级向第一个管道写入一个值,子级读取该值。子节点更新此值,并将其写入第二个方向管道。然后父级读取这个值和 Vuela! 双向管道通信。

输出:

Parent: writes value : 10
child: read value : 10
child: write value : 30
Parent: reads value : 30
Run Code Online (Sandbox Code Playgroud)

这可以扩展到您的应用程序

 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]);
  }
Run Code Online (Sandbox Code Playgroud)

如果你把它放在循环中,那么理论上它会起作用。然而,由于上下文切换和其他与操作系统相关的调度,两个进程之间的执行顺序会混乱。这意味着读取和写入不一定按照您的方式进行顺序操作,并且它不会起作用。阅读这个问题 如何等待数据写入管道的另一端