C语言 SIGALRM中断系统调用



我需要在超时后中断系统调用(在本例中为recvfrom)。为此,我使用alarm(),但是产生的SIGALRM会杀死我的进程,而不仅仅是中断系统调用。

我已经尝试调用signal(SIGALRM, SIG_IGN)来处理SIGALRM,但这会导致系统调用根本不会中断!我让这个工作的唯一方法是创建一个自定义的空处理程序(signal(SIGALRM, alrm_handler)) -处理程序不做任何事情,但它仍然导致recvfrom被中断而不杀死进程。

我理解默认的信号处理程序(SIG_DFL)将杀死进程,但我希望SIG_IGN忽略信号,但仍然中断系统调用。如果strace使用SIG_IGN和自定义空处理程序创建一个测试程序,它们最终都调用了没有SA_RESTART的rt_sigaction(SIGALRM...)。据我所知,如果SA_RESTART 设置了,那么系统调用将自动重新启动,但无论如何SIG_IGN都会发生这种情况!

有没有更干净的方法来中断系统调用与SIGALRM而不需要自定义信号处理程序?

当您告诉操作系统忽略一个信号时,如果它收到信号后什么也不做而忽略它,您不应该感到惊讶。POSIX只允许recvfrom在中断时返回EINTR,并且只有在调用信号处理程序时才会中断。当SIG_IGN设置为POSIX时,要求"信号的传递不会对进程产生影响"。

在套接字操作上设置超时的更好方法是使用setsockopt(fd, SOL_SOCKET, SO_RCVTIMEO, ...)在套接字上设置超时。如果超时,您将得到EAGAINEWOULDBLOCK错误。

您可能还想看看select,它可以潜在地消除使用超时的需要。

最新更新