2

如果我向以下程序发送多个后续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

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

4

2 回答 2

2

通常,您不能使用标准信号来执行此操作。Unix 内核通常只排队一个待处理的信号。如果 Sig2 和 Sig3 在 Sig1 处理程序中的进程休眠时发送,则它们将被合并。

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

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

于 2011-12-28T09:09:13.570 回答
1

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

于 2011-12-28T09:07:15.003 回答