如何捕获两个以上的连续信号

How to have more than two consecutive signals caught?

本文关键字:连续 信号 两个 何捕获      更新时间:2023-10-16

如果我向以下程序发送多个后续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 %dn", id);
        sleep(2);
    }
}
int main()
{
    int i;
    signal(SIGHUP, handler);
    for( i=0; ; i++ )
    {
        printf("%dn", 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内核通常只对一个待挂信号进行排队。如果Sig2和Sig3在Sig1处理程序中休眠时被发送,它们将被合并。

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

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

在Linux上,挂起信号只用一位表示。这意味着如果在处理程序已经运行时生成了多个信号,那么它只会被再次调用一次。