众所周知,某些阻止调用(如read
和write
)会返回-1并将errno
设置为EINTR
,我们需要处理此问题。
我的问题是:这是否适用于非阻塞呼叫,例如,将套接字设置为O_NONBLOCK
?
由于我读过的一些文章和消息来源说非阻塞调用不需要打扰,但我没有找到关于它的权威参考。如果是这样,它是否适用于不同的实现?
答案 0 :(得分:1)
@Mecki很好的解释。为了增加被接受的答案,“ Unix网络编程-第1卷,第三版”(Stevens)一书在第5.9节“处理中断的系统调用”中对慢速系统调用和其他系统进行了区分。我从书中引用-
我们使用术语“慢速系统调用”来描述
accept
,并且我们使用 这个术语是指可能永远阻止的任何系统调用。那就是 系统调用无需返回。
在同一部分的下一段中-
此处适用的基本规则是,在 缓慢的系统调用,进程捕获信号,并且该信号 处理程序返回时,系统调用可以返回错误
EINTR
。
按照这种解释,在非阻塞套接字上的read
/ write
并不是缓慢的系统调用,因此不应返回错误EINTR
。
答案 1 :(得分:0)
只是为了给@Mecki 的回答添加一些证据,我发现这个讨论是关于修复 Linux 中的一个错误,其中补丁导致非阻塞 recvmsg 返回 EINTR。声明如下:
<块引用>EINTR 总是表示您要求进行阻塞操作,并且 信号同时到达。
一旦你反转了这组条件的“阻塞”部分,EINTR 成为不可能的事件。
还有:
<块引用>看看我们为 AF_INET 做了什么。我们以正确的方式处理这件事。
如果我们在 lock_sock() 中休眠时被信号“中断”, recvmsg() 在非阻塞套接字上,我们正确返回 -EAGAIN,而不是 -EINTR。
我们可能为了获得套接字锁而休眠的事实是隐藏的 用户,它是内核的一个实现细节。
我们从不返回 -EINTR,如非阻塞套接字的联机帮助页中所述。