Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/linux/26.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 如何捕获两个以上的连续信号?_C++_Linux_Signals_Signal Handling - Fatal编程技术网

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

C++ 如何捕获两个以上的连续信号?,c++,linux,signals,signal-handling,C++,Linux,Signals,Signal Handling,如果我向以下程序发送多个后续的挂断信号,则只会处理其中两个,其余的将被忽略: #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);

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

#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;
}
如果我连续运行上述命令三次,第三个信号将被忽略,如下输出:

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

还有什么方法可以捕获第三个信号吗?

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

通常情况下,不能使用标准信号。Unix内核通常只对一个挂起的信号进行排队。如果在Sig1处理程序中进程休眠时发送Sig2和Sig3,则它们将合并

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


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

在信号处理程序中休眠是有问题的。它必须在那里吗?@wallyk根据手册页面,POSIX.1-2004需要
睡眠
才能在信号处理程序中保持安全。正常信号不排队,无论您做什么,您都会错过一些信号。请注意,异步信号处理程序中的printf不安全!必须了解信号的通信方式:当应用程序最终被中断时,它第一次知道自配置以来发生了>=1个事件,之后,自上次退出以来发生了>=0个事件。信号处理通常可以用一种有效的方式编写。信号处理程序通常应该为非异步线程设置一个标志以供参考:更多竞争条件。核心概念:无论有多少“子事件”创建或重申了工作要求,至少有一个信号会在相关工作完成后立即到达。在linux上输入
ulimit-a
时,我可以看到
挂起的信号
的默认值为16383。我还使用
getrlimit
和资源名
RLIMIT\u SIGPENDING
对它进行了测试(同样是16383)。那么linux如何仅用一个位来处理这个数量的挂起信号呢?@saeedn这是每个进程中每个用户(实际上是每个“真实用户ID”)可以挂起的信号总数。对于单个信号,每个进程,每种类型的信号只能挂起一个。
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