我需要在超时后中断系统调用(在这种情况下为recvfrom
)。为此,我使用alarm()
,但生成的SIGALRM会终止我的进程而不是仅中断系统调用。
我试过调用signal(SIGALRM, SIG_IGN)
来处理SIGALRM,但这会导致系统调用完全不被中断!我实现此功能的唯一方法是创建一个自定义的空处理程序(signal(SIGALRM, alrm_handler)
) - 处理程序不执行任何操作,但仍会导致recvfrom
被中断而不会导致进程被终止
我知道默认信号处理程序(SIG_DFL)将终止进程,但我希望SIG_IGN忽略该信号,但仍会中断系统调用。我strace
使用SIG_IGN和自定义空处理程序测试程序,他们最终都调用rt_sigaction(SIGALRM...)
而没有SA_RESTART。据我所知,如果SA_RESTART 已设置,那么系统调用将自动重启,但无论如何都会发生这种情况!
有没有更简洁的方法可以在不需要自定义信号处理程序的情况下使用SIGALRM中断系统调用?
答案 0 :(得分:2)
当您告诉操作系统忽略某个信号时,如果发出信号,则不应该感到惊讶,它不会做任何事情并忽略它。 POSIX仅允许recvfrom
在中断时返回EINTR,并且只有在调用信号处理程序时才会中断它。当SIG_IGN
设置为POSIX requires时,"信号的传递将不会对流程产生任何影响。"
在套接字操作上执行超时的更好方法是使用setsockopt(fd, SOL_SOCKET, SO_RCVTIMEO, ...)
在套接字上设置超时。如果超时,您将收到EAGAIN
或EWOULDBLOCK
错误。
您可能还想查看select
,这可能会消除使用超时的需要。