c++ - 如何捕获两个以上的连续信号?

标签 c++ linux signals signal-handling

如果我向以下程序发送多个后续 Hangup 信号,将只处理其中两个,其余的将被忽略:

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

int id;
void handler(int s)
{
    id++;
    int i;
    for(i=0; i<3; i++)
    {
        printf("Sig %d\n", id);
        sleep(2);
    }
}

int main()
{
    int i;
    signal(SIGHUP, handler);
    for( i=0; ; i++ )
    {
        printf("%d\n", i);
        sleep(1);
    }
    return 0;
}

我使用以下命令向进程发送信号:

kill -l {#process}

如果我连续三次运行上面的命令,第三个信号将被忽略,如下输出:

0
1
2
3
4
5
6
7
Sig 1
Sig 1
Sig 1
Sig 2
Sig 2
Sig 2
8
9
10
11
12

有什么办法也能捕捉到第三个信号吗?

最佳答案

通常情况下,您不能使用标准信号来做到这一点。 Unix 内核通常只排队一个未决信号。如果在 Sig1 处理程序中进程休眠时发送 Sig2 和 Sig3,则将它们合并。

您可以使用 sigaction(2) 来设置您的信号处理程序并为其提供 SA_NODEFER 标志。它将允许在仍在信号处理程序中时传递新信号。确保您的处理程序是可重入的,这是一个容易出错的解决方案。

还有称为“实时信号”的 POSIX.1b (POSIX.1-2001) 扩展。此类信号可以多次排队,但 SIGHUP 不是其中之一。 Linux 上的 signal(7) 声明实时信号编号为 33 (SIGRTMIN) 到 64 (SIGRTMAX)。

关于c++ - 如何捕获两个以上的连续信号?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8653463/

相关文章:

c++ - 无法计算数组平均值

c++ - 在 Ubuntu 12.04 上链接 - 对 `clock_gettime@GLIBC_2.17' 的 undefined reference

linux - 配置 linux 启动器以传递变量

c++ - 在 OpenCV 中创建 2D LoG 内核,就像在 Matlab 中创建 fspecial

c++ - 在 Windows 上使用 gdb 调试 MinGW 程序,而不是在断言失败时终止

linux - xm64 填满了我在 Linux Mageia 6 中的处理器资源

android - 如何从 Windows 中 Ping Linux Shell

在迷你 shell 中挂起 2 管道函数时,无法将信息存储在全局变量中

c - Glade、GtkBuiler 或 Gtk 意外地交换了信号处理程序

c++ - 我可以在Linux中检测箭头键作为信号吗?