[英]How to avoid blocking read() from named pipe after it closes
我有两个使用命名管道创建的进程。 编写器进程使用write()编写一条消息,而读取器进程通过read()读取该消息。 我注意到当作者关闭管道时,read()会阻塞。 是否可以让编写器进程在关闭管道之前发送EOF,以便不会阻塞阅读器?
不能...无法发送EOF
因为EOF
不能映射到通过通道发送的内容。 EOF
条件(是的,这是一个条件,不是您通过通道接收或发送的条件),意味着没有更多数据要read(2)
并且它是通过使read(2)
返回读取的0个字符得到的。 与在EOF
条件下进行的许多读取一样,它们将返回0
值,表示没有更多数据。
顺便说一句,当没有可用数据时,管道会阻止读取器,但是由于编写器仍在发送更多数据,因此没有EOF条件。 按照设计,当没有可用数据时,管道将阻止读取器(但写入器仍处于打开状态);当没有更多空间将数据放入fifo中时,管道将阻塞写入器(这种情况在有fifo打开的读取器中发生,但没有他们正在阅读),如您所见,它是一项功能,而不是错误。
如果要使read(2)
处于非阻塞状态并且在没有可用数据时将其设置为0
,则可以使用O_NONBLOCK
标志open(2)
(或稍后通过fcntl(2)
系统调用进行操作),这将使read(2)
fcntl(2)
read(2)
立即返回可用数据(即使没有可用数据),但是它有一个缺点:那么您无法将没有可用数据(尚未写入)的fifo与实际的EOF
(作者关闭了它的作者)区分开来。 ),因为两者都将返回0
。
顺便说一句,在谈论文件条件结束时,我不喜欢使用EOF
常量,因为它增加了对其定义的混淆。 EOF
是文件条件结束时 getchar(3)
返回的值,但不是char
(如果检查getchar(3)
的定义,您会发现它的定义为int
而不是char
,这是为了添加EOF
条件限制为可能的char
值的整个范围---因此,从getchar(3)
返回257个可能的值,数据为0-256
,文件结束条件为EOF
)
如果要让编写者发信号通知文件结束,则必须close(2)
fifo并重新打开它。
当编写器关闭管道时,即使它被阻塞(例如,它将醒来),读取器也不会阻塞。 读调用将返回0,指示管道上的EOF。 读者应该这样做:
rlen = read(pipefd,buf,sizeof(buf));
if (rlen <= 0)
break;
您是否正在检查返回码?
在写入器中,如果读取器过早关闭了管道(例如,它已中止),则写入器将从写入-1并将errno设置为EPIPE时获得返回。 它还可以获取SIGPIPE。
见男人7管...
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.