我正在套接字上使用接受调用,该套接字只应接受与客户端进程的连接。然而,使用信号 SIGALRM 的 sigaction 实现的信号处理程序被注册为可行的连接。我想我应该检查与 select 或 poll 的连接,但我不确定这是否会让事情变得复杂。任何帮助将不胜感激。
编辑:抱歉说这是一个连接。这似乎只是一种联系。我的代码有一个 while 循环,其条件是只要accept 的计算结果不为 0 就运行。
更新:所以我刚刚发现了我的问题。 sigaction 标志是默认值。我将其更改为 SA_RESTART 并接受现在工作正常。我认为这与忽略原始 I/O 并返回 EINTR 有关,但我对此并不完全确定。有人知道吗?
最佳答案
在 Linux 上,系统调用(包括 accept
)可以被信号中断。
如果在系统调用正在进行时收到信号,系统调用将被中止并返回错误EINTR
。尽管这是一个“错误”,但这并不意味着出了问题,它只是意味着您必须再次尝试调用。这种设计背后的推理相当复杂,超出了这个问题的范围。
正如您所发现的,您可以设置 sigaction
标志 SA_RESTART
以防止特定信号发生这种情况。如果遇到错误,accept
将返回 -1,因此这看起来像:
while(1)
{
int client_sock = accept(...);
if(client_sock == -1)
{
if(errno == EINTR)
continue; // try again
... normal error handling here ...
}
else
{
... normal connection handling here ...
}
}
更可靠的解决方案是专门检查 EINTR - 以防您的程序收到未准备好的信号,或者其他代码使用信号且未设置 SA_RESTART。 (这可能是您 3 个月后编写的代码)
关于c - 接受信号处理程序干扰的调用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34173526/