我正在调试以下代码:
signal(SIGALRM, testt);
alarm(1);
result = recvfrom( listening_socket, buf, maxlen, 0, &from, &fromlen );
printf("stoped\n");
正如man 3 siginterrupt
所述,警报应该中断系统调用,但在我的情况下它不会。调用警报处理程序,但recvfrom
不会中断。
但是,当使用signal(2)函数指定新的信号处理程序时,系统调用默认会中断。
如果我在设置警报处理程序后添加siginterrupt(SIGALRM, 1);
,则recvfrom
会按预期中断。
我错过了什么?我的代码出了什么问题?
注意:用signal
替换sigaction
不是我想要的。
答案 0 :(得分:9)
siginterrupt(3)
联机帮助页不正确(Linux联机帮助页的version 3.33更正了错误)。 glibc的signal
的默认行为是建立一个不中断系统调用的信号。您可以使用strace
:
void handler(int unused) {}
int main(void)
{
signal(SIGALRM, handler);
}
⟶
$ strace -e trace=rt_sigaction ./a.out
rt_sigaction(SIGALRM,
{0x4005b4, [ALRM], SA_RESTORER|SA_RESTART, 0x7fe732d3d490},
{SIG_DFL, [], 0}, 8) = 0
注意那里的SA_RESTART。您可以继续执行您正在执行的操作 - 在建立处理程序后调用siginterrupt(SIGALRM, 1)
- 或者您可以切换到使用sigaction
,这将允许您按照第一个方式设置标记地点。你说你不想这样做(为什么?)但是这就是我的建议。