简体   繁体   English

不能捕获多个中断

[英]Can't catch more than one interrupt

I want my program to run in a loop until it receives an alarm signal, in the meantime I want to run some code every time it receives an interrupt signal. 我希望我的程序在收到警报信号之前一直循环运行,与此同时,我想在每次收到中断信号时运行一些代码。

The following almost works: 以下几乎可以正常工作:

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");
}

The problem is that it only works for the first interrupt signal. 问题在于它仅适用于第一个中断信号。 The second interrupt kills the program (without printing "done") regardless. 第二个中断将终止程序(不打印“完成”)。

So the output I see is 所以我看到的输出是

^Cinterrupted
^C

when I want to see 当我想看的时候

^Cinterrupted
^Cinterrupted
done

Do not use signal() to install custom signal handlers, as its behavior in that case varies across implementations. 不要使用signal()安装自定义信号处理程序,因为在这种情况下其行为会因实现而异。 In particular, on some systems, if signal() is used to set a custom signal handler for a given signal, then that signal's disposition is reset when the signal is received. 特别是在某些系统上,如果使用signal()设置给定信号的自定义信号处理程序,则在接收到该信号时会重置该信号的处理方式。 That's what you seem to be observing, but you cannot portably rely on it. 那就是您似乎正在观察的东西,但是您不能轻而易举地依靠它。

Instead, install signal handlers via sigaction() . 而是通过sigaction()安装信号处理程序。 Among other things, it has a mechanism for specifying whether the handler should be reset upon receipt of the signal. 除其他外,它具有一种机制,用于指定是否应在收到信号后重置处理程序。

Signal handlers set with signal() are disarmed when the signal handler is called in response to a signal. 当响应信号而调用信号处理程序时,撤消设置有signal()的信号处理程序。 You have to rearm the signals each time: 您每次必须重新准备信号:

void catch_interrupt(int x)
{
    interrupted = true; 
    signal(SIGINT, catch_interrupt);

}

void catch_alarm(int x)
{
    waiting = false;
    signal(SIGALRM, catch_alarm);
}

Yes, that means there is a small window of vulnerability when the first signal has been handled but the handler has not yet been reinstated when a second signal will cause the program to react as if no signal handler is installed (because no signal handler is installed). 是的,那么这是指当第一信号已经被处理的漏洞的一个小窗口,但处理程序时的第二信号将导致程序作出反应,如果没有安装信号处理程序(因为没有安装信号处理程序尚未被恢复)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM