2014-11-08 198 views
1

学习为C.等待叉孩子继续

下面的代码约fork()pipe()之前写到管道创建一个管道和一个子进程。孩子发送消息,父母读取消息。

int main() { 
    int  fd[2]; 
    pid_t pid; 
    pipe(fd); 
    pid = fork(); 
    if (pid == 0) { 
     // Child 
     close(fd[0]); 
     write(fd[1], "HELLO", (strlen("HELLO")+1)); 
     exit(0); 
    }else{ 
     // Parent 
     close(fd[1]); 
     char buffer[80]; 
     read(fd[0], buffer, sizeof(buffer)); 
     printf("Received string: %s", buffer); 
    } 
    return 0; 
} 

它工作正常。如果您对write行发表评论,则父级会报告它收到了一个带有奇怪字符的字符串,我认为这是正常的,因为它正在读取与我的程序无关的内存。

但后来,它带来的问题:是不是有可能父阅读管之前孩子可以写数据?如果发生这种情况,它会读奇怪的字符。

父母如何“等待”从孩子那里写入数据?

将来我可能会有几个孩子的过程,我希望父母在继续之前等待所有孩子完成他们的工作。

+1

检查返回的值* *全部**这些系统调用。你看到垃圾是因为你盲目地阅读没有写入的东西。 – Mat 2014-11-08 08:55:25

+0

@Mat:什么系统调用?你的意思是'fork()'和'pipe()'? – Voldemort 2014-11-08 09:05:45

+0

...和“读”和“写”。所有这些都可能失败,即使他们没有返回的信息对于制定正确的计划也是必要的。 (对于失败的“关闭”,通常你可以做的不多,但它也可能失败。) – Mat 2014-11-08 09:09:18

回答

1

如果你对此有何评论写行,家长会报告说,如果到write中的呼叫孩子跳过它接受一个字符串奇怪的字符

,子进程结束,孩子的写作管端的末端关闭。

父级检测到,孩子的管道末端已关闭,这使read()的调用返回。父母实际上没有读任何东西,所以缓冲区保持未初始化并且“垃圾”被打印出来。

请找到下面read's POSIX specification的relvant部分:

当试图从一个空的管道或FIFO读:

  • 如果没有进程打开写作的管道,阅读()应返回0表示文件结束。

[...]

  • 如果某些进程打开了写作的管道和O_NONBLOCK清晰,阅读(),直到一些数据被写入或管道被关闭,应阻塞调用线程所有的管道都可以写入。

为了使你的代码来处理孩子的情况下,不写任何东西,测试是否父为“调用read()`真的读的东西:

  ssize_t result = read(fd[0], buffer, sizeof(buffer)); 
      if (-1 == result) /* Also ALWAYS test for error. */ 
      { 
       perror("read() failed"); 
      } 
      else if (0 == result) 
      { 
       fprintf(stderr, "read() returned without having read anything.\n") 
      } 
      else 
      { 
       printf("Received string: '%s'", buffer); 
      }