2015-10-05 111 views
1

我想在C中的一个子作家和一个父阅读器之间建立一个管道。 我认为我的父进程必须等待它的子进程才能够读取它,然后我要检查它,所以我写了下面的代码:父进程中的read()是否等待管道中的子写()?

pipe(fd); 
// ... checks for pipe 
pid_t pid = fork(); 
// ... checks for fork 
if (pid == 0) { 
    close(fd[0]); 
    // Long sleep hoping parent will terminate before the write() 
    sleep(10); 
    write(fd[1], "hello", strlen("hello") + 1); 
    close(fd[1]); 
} else { 
    close(fd[1]); 
    read(fd[0], buf, sizeof(buf)); 
    printf("received: %s\n", buf); 
    close(fd[0]); 
} 
return 0; 

输出是意外(或不是吗?)received: hello。 如果我用for (volatile int i = 0; i < some_big_int; ++i);循环将呼叫替换为sleep(),则输出相同。 我不认为调用read()会阻止我的父进程,直到子进程在管道的另一端写入,但我无法解释这种行为。任何提示?

+1

这是预期的操作:I.E. 'read()'块,将在所请求的总字节数被读取或遇到eof时返回。或某些错误事件和信号 – user3629249

+0

我无法找到“man 2 read”中所说的内容:例如这个句子似乎表明,如果没有什么要读,read()返回并且是非阻塞的:'在没有任何错误的情况下,或者如果read()不检查错误,则read() 0返回零并且没有其他效果。' – hdl

+1

当'read'在流fd(例如管道)上传递非零count时,它会阻塞,直到至少有1个字节可用,然后读取'计数“,因为它可以在那个时候。既然你写了'close'(写入小于'PIPE_BUF'),它会立即刷新整个字符串,所以当它解除封锁时,它会立即写入所有内容。 – ShadowRanger

回答

2

read将阻塞,直到至少有一个字节要读取,或遇到错误,或者到达流的末尾。当至少有一个字节要读取时,它将读取尽可能多的字节(最多可指定的最大数量),然后返回。

在这种情况下,父进程对read的调用将阻塞,直到子进程write对管道有某种东西。


man 7 pipe上管和FIFO I/O:

如果一个进程试图从空管到读,然后读(2)将阻塞,直到可用的数据。如果一个进程试图写入一个完整的管道(见下文),那么写入(2)块直到从管道读取足够的数据以允许写入完成。通过使用fcntl(2)F_SETFL操作来启用O_NONBLOCK打开文件状态标志,可以实现非阻塞I/O。

+0

这是在哪里指定的?不幸的是,我的ID没有在'man 2 pipe'和'man 2 read'中找到这个信息。 – hdl

+0

在'man 7 pipe'中找到它,并相应地编辑你的答案。非常感谢你。 – hdl

相关问题