EINTR和非阻塞呼叫

时间:2013-01-03 07:04:27

标签: nonblocking eintr

众所周知,某些阻止调用(如readwrite)会返回-1并将errno设置为EINTR,我们需要处理此问题。

我的问题是:这是否适用于非阻塞呼叫,例如,将套接字设置为O_NONBLOCK

由于我读过的一些文章和消息来源说非阻塞调用不需要打扰,但我没有找到关于它的权威参考。如果是这样,它是否适用于不同的实现?

2 个答案:

答案 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,如非阻塞套接字的联机帮助页中所述。

来源:https://patchwork.ozlabs.org/project/netdev/patch/1395798147.12610.196.camel@edumazet-glaptop2.roam.corp.google.com/#741015