我希望我的程序在循环中运行,直到收到报警信号,同时我想在每次收到中断信号时运行一些代码。
以下几乎可行:
bool volatile waiting = true;
bool volatile interrupted = false;
void catch_interrupt(int x)
{
interrupted = true;
}
void catch_alarm(int x)
{
waiting = false;
}
void alive()
{
signal(SIGINT, catch_interrupt);
signal(SIGALRM, catch_alarm);
alarm(10);
while (waiting)
{
if (interrupted)
{
printf("interrupted\n");
interrupted = false;
}
}
printf("done\n");
}
问题是它只适用于第一个中断信号。无论如何,第二个中断都会终止程序(不打印“完成”)。
所以我看到的输出是
^Cinterrupted
^C
当我想看
时^Cinterrupted
^Cinterrupted
done
答案 0 :(得分:4)
不要使用signal()
来安装自定义信号处理程序,因为在这种情况下它的行为因实现而异。特别是,在某些系统上,如果signal()
用于为给定信号设置自定义信号处理程序,则在接收到信号时将重置该信号的处置。这就是你似乎在观察的东西,但你无法依赖它。
而是通过sigaction()
安装信号处理程序。除此之外,它还有一种机制,用于指定在收到信号时是否应重置处理程序。
答案 1 :(得分:2)
当响应信号调用信号处理程序时,设置为signal()
的信号处理程序将被撤防。你必须每次重新安装信号:
void catch_interrupt(int x)
{
interrupted = true;
signal(SIGINT, catch_interrupt);
}
void catch_alarm(int x)
{
waiting = false;
signal(SIGALRM, catch_alarm);
}
是的,这意味着当第一个信号被处理但处理器尚未恢复时,有一个小漏洞窗口,当第二个信号将导致程序作出反应,好像没有安装信号处理程序(因为没有信号)处理程序已安装。