首页 > 解决方案 > 解除阻塞信号后代码不执行第二部分

问题描述

我正在通过使用sigaction. 在做自己的练习时,我试图先阻止信号(SIGINT 和 SIGQUIT),然后再解除阻止。

在我的终端输出中,在信号被阻塞的for循环中,如果我尝试按Ctrl+C或Ctrl+,它仍然会打印出如下语句,但是在解除阻塞后,它不会打印出内容在第二个 for 循环中。

(block) working ....
(block) working ....
^C(block) working ....
(block) working ....
^\(block) working ....
The work is done, now you can ...

但是,如果我在第一个 for 循环中的程序执行期间没有尝试按 Ctrl+C 或 Ctrl+\,那么第二个 for 循环将被打印出来。

(block) working ....
(block) working ....
(block) working ....
(block) working ....
(block) working ....
The work is done, now you can ...
(unblock) working ....
(unblock) working ....
(unblock) working ....
(unblock) working ....
(unblock) working ....

我希望达到的预期结果如下:

(block) working ....
(block) working ....
^C(block) working ....
(block) working ....
^\(block) working ....
The work is done, now you can ...
(unblock) working ....
^C

在其中我可以尝试在第一个 for 循环期间多次按 Ctrl+C 或 Ctrl+\ 次,然后在进入第二个 for 循环时按任一信号将终止命令。

这是我的代码:

#include <signal.h>
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>

int main()
{
    int i;
    sigset_t sigs, sigs2;

    sigemptyset(&sigs);
    sigaddset(&sigs, SIGINT);
    sigaddset(&sigs, SIGQUIT);

    sigprocmask(SIG_SETMASK, &sigs, NULL); // tried with SIGBLOCK, same issues


    for (i=0; i<5; ++i)
    {
        printf("(block) working ....\n");
        sleep (1); 
    }
    printf("The work is done, now you can ...\n");

    // unblock signals
    sigprocmask(SIG_UNBLOCK, &sigs, NULL);

    for (int j=0; j<5; ++j)
    {
        printf("(unblock) working ....\n");
        sleep (1); 
    }
    exit(0);
}

提前欣赏任何见解。

标签: csignals

解决方案


阻止信号与忽略信号不同。如果一个信号被发送到一个进程,而该信号被该进程阻塞,那么它会保持挂起状态,直到信号被解除阻塞或进程终止。

这正是你所观察到的。当那些被阻止时,您将 aSIGINT和 a传递给您的进程。SIGQUIT一个在它们被解除阻塞后立即交付,在进入第二个循环之前终止该过程。

哪个实际交付(第一个)未指定,但如果一个已注册处理程序,因此它不会终止进程,那么两者都可能被交付,甚至对于第一个接收到的处理程序也是可能的因收到第二个而中断。

但是,相同规则信号的倍数不会排队。例如,无论SIGQUIT您在该信号被阻塞时发送了多少个 s,当该信号被解除阻塞时,等待发送的不会超过一个。


推荐阅读