通过C管道进行通信

时间:2016-01-20 21:16:53

标签: c process pipe parent-child

我正在尝试编写这个小程序,其中父级和子级通过管道相互通信,这里的代码可以工作,除非你“取消注释”注释行,而不是某种死锁,而我想不清楚为什么?有什么想法吗?

int main(int argc, char **argv){

  int fd[2];
  int fd2[2];
  pid_t pid;
  pipe(fd);
  pipe(fd2);
  pid = fork();

  if(pid==0){
      close(fd[1]);
      dup2(fd[0],fileno(stdin));
      close(fd2[0]);
      FILE *output = fdopen(fd2[1],"w");
      char buffer[255];
      while(fgets(buffer,255,stdin)!=NULL)
          printf("child: %s",buffer);
  //  fprintf(output,"%s",buffer);
  } else {
      close(fd[0]);
      close(fd2[1]);
      FILE *output = fdopen(fd[1],"w");
      char buffer[255];
      while(fgets(buffer,255,stdin)!=NULL)
          fprintf(output,"%s",buffer);
      //FILE *input = fdopen(fd2[0],"r");
      //while(fgets(buffer,255,input)!=NULL)
      //  printf("Parent: %s",buffer);
  }

  return 0;
}

3 个答案:

答案 0 :(得分:1)

父级需要将管道的一侧关闭到子级,以便子级将检测到文件结束并终止。

  while(fgets(buffer,255,stdin)!=NULL)
      fprintf(output,"%s",buffer);
  fclose(output); // does close(fd[1]);
  FILE *input = fdopen(fd2[0],"r");
  while(fgets(buffer,255,input)!=NULL)
    printf("Parent: %s",buffer);

答案 1 :(得分:1)

确保一切都关闭。之后

dup2(fd[0],fileno(stdin));

你应该这样做:

close(fd[0]);

答案 2 :(得分:1)

如果两个(单线程)进程之间有输入和输出管道,则可以有一些deadlock,因此需要使用多路复用系统调用event loop(通常为{{3}根据可能的情况,你会读或写。当然你需要缓冲!顺便说一句,在这种情况下,您最好不使用<stdio.h>来使用低级poll(2)(如果您仍然使用stdio,请不要忘记syscalls(2) .. ..)。另请参阅fflush(3)

(当然我假设是POSIX或Linux系统)