管道C的行为

时间:2015-06-10 12:15:47

标签: c pipe fifo

我有这段代码:

#include <stdio.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/types.h>
#include <signal.h>
#define READ 0
#define WRITE 1

char* phrase = "Hello";

void PIPE(){

    int fd [2], bytesRead;
    char message [100]; /* Parent process' message buffer */
    pipe (fd); /*Create an unnamed pipe */

    if (fork () == 0) /* Child, writer */
    {
        close(fd[READ]); /* Close unused end */
        write (fd[WRITE],phrase, strlen (phrase) + 1); 
        close (fd[WRITE]); /* Close used end*/
    }
    else /* Parent, reader*/
    {
        close (fd[WRITE]); /* Close unused end */
        bytesRead = read (fd[READ], message, 100);
        printf ("Read %d bytes: %s\n", bytesRead, message); /* Send */
        close (fd[READ]); /* Close used end */
    }
}

我正在用C学习管道,我的书说:

If a process reads from a pipe whose write end has been closed, the read () returns a 0, indicating end-of-input.

但是在代码中(在父部分中),在读取函数之前,写入部分已经关闭,而读取函数不会返回0但是5(Hello的长度)。

出了什么问题?

感谢您的时间

更新1:

我还有另一个问题(我理解第一个问题):

如果读者读取空管道,那么读取函数会返回0,但我怎么能确定这是第一个开始然后读写的作者?

3 个答案:

答案 0 :(得分:1)

一旦所有书面数据都被阅读&#34;它应该包括&#34;否则管道就没有多大意义了。或者需要明确地向编写者发出信号,读者在关闭之前已经从管道获取了所有数据 - 打破了它的文件语义。

答案 1 :(得分:0)

对于 empty 管道,如POSIX所说:

  

尝试从空管道或FIFO读取时:

If no process has the pipe open for writing, read() shall return 0 to indicate end-of-file

回答更新1:

管道(在正常阻塞模式下)在两端提供同步:管道为空时读取器被阻塞,管道满时阻塞写入器。

您无需在读者阅读之前确保作者写作或类似的东西。如果读者试图读取一个空管道,它将被阻塞,直到:其他人写入管道或最后一个作者关闭它。

答案 2 :(得分:0)

首先,当父母从中读取时,您不知道管道是否已关闭。由于涉及两个过程,因此调度程序决定下一个进程和多长时间运行 - 而不是代码的顺序。

其次,正如已经说过的那样,写入管道的字符串仍然在它的缓冲区中。因此,父级将在返回EOF之前读取缓冲区中的所有内容。