我有这段代码:
#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,但我怎么能确定这是第一个开始然后读写的作者?
答案 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之前读取缓冲区中的所有内容。