Wil*_*mKF 5 c++ select eintr infinite-loop
我有一个包含此功能的 C++ 应用程序:
int
mySelect(const int fdMaxPlus1,
fd_set *readFDset,
fd_set *writeFDset,
struct timeval *timeout)
{
retry:
const int selectReturn
= ::select(fdMaxPlus1, readFDset, writeFDset, NULL, timeout);
if (selectReturn < 0 && EINTR == errno) {
// Interrupted system call, such as for profiling signal, try again.
goto retry;
}
return selectReturn;
}
Run Code Online (Sandbox Code Playgroud)
通常,这段代码工作得很好,但是,在一个例子中,我看到它进入了一个无限循环,代码select()不断失败EINTR errno。在这种情况下,调用者已将超时设置为零秒和零微秒,这意味着不要等待并select()立即返回结果。我认为EINTR只有在信号处理程序发生时才会发生,为什么我会一遍又一遍地获得信号处理程序(超过 12 小时)?这是 Centos 5。一旦我将其放入调试器以查看发生了什么,经过几次迭代后,代码返回而没有 EINTR。请注意,被检查的 fd 是一个套接字。
我可以为上述代码添加重试限制,但我想先了解发生了什么。
在 Linux 上,select(2)可以修改超时参数(通过地址传递)。所以你应该在通话后复制它。
retry:
struct timeout timeoutcopy = timeout;
const int selectReturn
= ::select(fdMaxPlus1, readFDset, writeFDset, NULL, &timeoutcopy);
Run Code Online (Sandbox Code Playgroud)
(在您的代码中,timeout经过几次甚至第一次迭代后,您的值可能为零或非常小)
顺便说一句,我建议使用poll(2)代替select(因为poll它对 C10K 问题更友好)
顺便说一句,即使没有注册的信号处理程序,EINTR也会发生在任何信号上(请参阅signal(7) )。
您可能会用来strace了解程序的整体行为。