我不是很理解“关闭管道的写端”和“不向管道写任何内容”之间的区别。如果我不向管道写任何东西,而且管道是空的,那么为什么读取端只是阻塞而不是读取EOF?这与关闭写端有何不同?
从管道(或任何地方)读取EOF表示没有更多的输入,并且将来也不会有更多的输入。
如果此刻没有可用的输入,但管道未关闭,则读取器(默认情况下)将阻塞等待输入;如果写入器随后向管道写入数据,则该数据将对读取器可用。 EOF会告诉读取器停止尝试读取更多数据。
fgetc()
,它将返回 EOF
,这是一个负的 int
值,与任何 unsigned char
值都不同。一些其他函数返回读取的项目数;例如,read()
函数返回 0
表示文件结束。(或错误条件。) - Keith Thompsonread()
级别上,如果您在获取零字节后尝试再次读取,则会在下一个数据中继续。在标准I/O级别上,一旦您从文件获取EOF(或错误),则会继续获取它,直到重新定位流(fseek()
等)或清除错误(clearerr()
)。示例代码见下一条评论。(在其中输入文本行;在一行的中间或开头键入Control-D;您需要生成5个EOF消息才能退出。) - Jonathan Leffler#include <unistd.h> #include <stdio.h> int main(void) { char buffer[4096]; int nbytes; int eof_count = 0; int read_count = 0; while (eof_count < 5) { while ((nbytes = read(0, buffer, sizeof(buffer))) > 0) printf("[%d:%d]<<%.*s>>\n", ++read_count, nbytes, nbytes, buffer); if (nbytes == 0) printf("EOF %d detected\n", ++eof_count); else if (nbytes < 0) { puts("Error detected - exiting"); break; } } puts("All done"); return 0; }
- Jonathan Leffler这就是与阻塞文件描述符相关的协议。管道的读端等待数据。关闭它的写端表示数据流结束。这实际上是一个强大的同步概念。
您可以将管道切换到非阻塞模式,其中缺少数据被视为软错误,因此您只需检查是否有任何可读内容。当您需要从多个文件描述符中读取(比如在处理多个客户端的服务器中),这非常有用。这就是IO多路复用发挥作用的地方。