C信号的捕获顺序与它们发送的顺序不同(或者根本没有捕获)

  • 本文关键字:顺序 或者 信号 c signals
  • 更新时间 :
  • 英文 :


我有两个程序,一个接收信号,另一个向第一个发送信号。我只使用SIGUSR1和SIGUSR2来实现这一点,它不会按照发送信号的顺序捕获信号。我在一些帖子中看到,SIGUSR2在发送时与SIGUSR1相反,但我将两个信号都放入了sigaction掩码中,因此在处理程序运行时应该阻止它们。我写了一个可重复的最小例子来说明我的问题:

发件人程序(客户端(:

#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <signal.h>
int main(int argc, char **argv)
{
int ppid;
if (argc != 2)
return (-1);
ppid = atoi(argv[1]);
for (int i = 0; i < 10; i++)
{
if (i % 2) {
kill(ppid, SIGUSR1);
printf("1n");
}
else
{
kill(ppid, SIGUSR2);
printf("2n");
}
}
return (0);
}

Catcher程序(服务器(:

#include <signal.h>
#include <stdio.h>
#include <unistd.h>
void    sig_handler(int sig)
{
if (sig == SIGUSR1)
printf("1n");
else if (sig == SIGUSR2)
printf("2n");
}
int main(void) {
struct sigaction act;
printf("%dn", getpid());
sigemptyset(&act.sa_mask);
sigaddset(&act.sa_mask, SIGUSR1);
sigaddset(&act.sa_mask, SIGUSR2);
act.sa_flags = 0;
act.sa_handler = sig_handler;
sigaction(SIGUSR1, &act, 0);
sigaction(SIGUSR2, &act, 0);
while (42)
pause();
return (0);
}

我首先启动服务器以获取其PID,然后用服务器的PID作为第一个参数运行客户端,然后在客户端上获得输出:

2
1
2
1
2
1
2
1
2
1

我希望它在服务器上是一样的,但我得到了:

2
1
1
1
2
2
1
2
1

显然,有一个SIGUSR2没有被捕获,信号的接收顺序也不相同,这是怎么回事?

编辑:我重新进行了一些测试,有时我的程序会错过一堆信号,我会得到这样的输出:

2
1
2

Donot从信号处理程序调用printf。按照以下方式更改代码以获得更好的行为。

void    sig_handler(int sig)
{
if (sig == SIGUSR1)
write(1, "1n", 2);
else if (sig == SIGUSR2)
write(1, "2n", 2);
}

由于假定write将同时写入所有字节的错误,此代码仍然是错误的。它不会总是这样,所以你可能会丢失一些换行符,但行为会比以前更明显。但你仍然会看到无序的书写。

这不能正常工作的原因是在处理信号时可以也将接收到信号。CCD_ 3不是重入者,所以会出现任意的不良行为。许多琐碎的示例在信号处理程序中调用printf,因为它们知道或假设它是安全的,而大多数实际用例都可以逃脱惩罚,因为实际冲突很少,但您通过在紧密循环中发送信号使其变得常见。

此外,也不能真正保证信号按照发送的顺序接收。

显然有一个SIGUSR2没有被捕获,并且信号的接收顺序不同,这是怎么回事?

没有问题。信号从来没有保证它们会按照发送顺序被捕获。也不能保证发送一个以上的信号实例会导致该信号的一个以上实例被捕获。

所有可以保证的是,如果你发送一个特定的信号,就会收到相同的信号。如果您发送了两次SIGUSR2,然后收到了一个SIGUSR2。那么在这两种情况下,都收到了相同的信号。

在典型的实现中,每个过程都有一个";是/否";标志。发送该信号将该标志设置为"0";是";并且接收该信号将其设置为"0";否";。按任一顺序发送SIGUSR1和SIGUSR2只会导致SIGUSR1与SIGUSR2标志都被设置为"0";是的";。如果标志已经设置为"0";是";,发送信号没有效果。

听起来你把信号用于信号之外的其他目的,这不是一个好主意。请使用套接字、管道、常规文件、共享内存或其他文件。

相关内容

最新更新