繁体   English   中英

如何避免关闭后从命名管道阻止read()

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM