【问题标题】:Communicating via pipes in C在 C 中通过管道进行通信
【发布时间】:2016-01-20 21:16:53
【问题描述】:

我正在尝试编写这个小程序,父母和孩子通过管道相互通信,这里的代码有效,除非你“取消注释”注释行,否则会出现某种死锁,我无法弄清楚为什么?有什么想法吗?

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

【问题讨论】:

  • 你认为应该先终止哪个进程,父进程还是子进程?
  • @DavidSchwartz 孩子。但是如果我等待子进程,那么它又是一个死锁。
  • 孩子如何终止?它的while 循环等待它的stdin 关闭。父母在哪里关闭它?父级中的close(fd[1]) 在哪里?
  • @DavidSchwartz 它在到达 EOF (ctrl + D) 时终止,然后输出它读取的内容
  • 没有 EOF。父级从不执行close(fd[1]),这将指示文件结束。如果您想向子节点发送 EOF,则父节点需要关闭管道的末端。

标签: c process pipe parent-child


【解决方案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);

【讨论】:

  • 谢谢你现在没有更多的死锁了!!但是输出是乱码……知道为什么吗?
  • 哦,好吧...我超级累了,我做了 close(fd[0]) 而不是 fclose(output)。谢谢先生,你就像一个调试忍者
【解决方案2】:

确保一切都关闭。之后

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

你应该这样做:

close(fd[0]);

【讨论】:

    【解决方案3】:

    当你在两个(单线程)进程之间有输入和输出管道时,你可以有一些deadlock,所以你需要有一个使用多路复用系统调用的event loop(通常是poll(2)...)你要么读要么写,这取决于可能的情况。当然需要缓冲!顺便说一句,在这种情况下,你最好使用低级别的syscalls(2),而不使用<stdio.h>(如果你仍然使用stdio,别忘了fflush(3)....)。另见this answer

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

    【讨论】:

      猜你喜欢
      • 2011-02-09
      • 2010-12-26
      • 2017-09-10
      • 1970-01-01
      • 2011-12-22
      • 1970-01-01
      • 2022-12-10
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多