管道中传输的数据是垃圾

时间:2014-11-14 20:47:07

标签: c pipe exec fork named-pipes

我正在使用这两个this回答的程序。这个答案使用命名管道而不是管道,我是否正确?

我写了main.c,它实际上是我实际项目的代码,最小化到这个特定问题(这就是为什么我有一个for循环的例子)。

#include <unistd.h>
#include <sys/wait.h>
#include <stddef.h>
#include <limits.h>
#include <stdio.h>


int main(void) {
  pid_t pid;

  int i;
  for(i = 0; i < 2; ++i) {
    pid = fork();
    if (pid == -1) {
      // error, failed to fork()
      perror("failed to fork()");
      return 1;
     } else if (pid == 0) {
      // child code
      if(i < 1) {
        // the writer.c
        char* arg_list[] = { "w", NULL };
        execv( "w", arg_list );
        printf("exec FAILED\n");
      } else {
        // the reader.c
        char* arg_list[] = { "r", NULL };
        execv( "r", arg_list );
        printf("exec FAILED\n");
      }
     }
    }

    // parent code
  int status;
  // wait for all children to terminate
  while ((pid = wait(&status)) > 0) {
    if (status == 1) {
      printf("The child process terminated with an error!\n");
      return -1; 
    }
  }
  printf("All children are done\n");

  return 0;
}

问题在于有时,读者会收到垃圾(或者很可能没有)并且它会挂断。

示例输出:

Received: Hi
All children are done
samaras@samaras-A15:~/test$ ./m
Received: Hi
All children are done
samaras@samaras-A15:~/test$ ./m
Received:        <----------------- This is garbage, that is not reproducible 
^C

那么,我错过了什么?

无需在下面阅读。


我的猜测是(没有检查,所以如果我是正确的,我仍然需要澄清):

读者在作家面前跑,这就是为什么它有垃圾,但为什么它会挂起?

我需要编写一个包装函数read_all()(还有一个用于写案例?),它收集管道吐出的所有数据,但为什么如果我更换&#34;嗨&#34;与&#34; H&#34;,我有相同的行为?


编辑:

如果我的第一个猜测就是这种情况,我会设置一个循环进行阅读,但是在读者首先启动的情况下它将永远执行。

在我看到垃圾的情况下,在使用strace -f后,我得到了这个:

...
[pid  3326] read(-1, 0xbfddd80c, 1024)  = -1 EBADF (Bad file descriptor)^C
Process 3324 resumed
Process 3325 detached
Process 3326 detached

1 个答案:

答案 0 :(得分:1)

你的循环(或缺乏)与它无关。当您的阅读器打开(open())管道,以便在writer创建管道之前进行读取,然后读者等待的文件描述符无效(-1)。因此,即使作者稍后写了一些内容,读者也会等待无效的fd(-1)并且永远不会读取任何内容。平凡的,您可以通过以下方式解决它:

while( (fd = open(myfifo, O_RDONLY)) == -1); 

在读卡器中等待管道可用。我其实想知道是否有比这更好的方法。我能想到的另一种方法是access()上的循环,但它与此并没有太大的不同......