当我向服务器发送大量 kill() 命令时,我的服务器无法处理所有信号

my server doesn't handle all signals when I send it a lot of kill() commands

我对这段小代码有疑问。我有一个 "server" 和一个 "client"。服务器等待来自客户端的SIGUSR1。但是当我循环发送 SIGUSR1 时,服务器不会处理每个信号! 我每次收到一个信号都会i++,当我发送1000个信号时我得到981。

usleep()sleep() 没有帮助。

这里是客户端代码:

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

int     main(int ac, char **av)
{
  int   i = 0;
  int status = 0;

  if (ac < 2)
    return (0);
  printf("kill %s (%d)", av[1], atoi(av[1]));
  for (i=0;i<=1000;i++)
    {
      printf("%d\n", i);
      kill(atoi(av[1]), SIGUSR1);
    }
  kill(atoi(av[1]), SIGUSR2);
}

和服务器代码:

#include <signal.h>
#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
#include <string.h>
#include <stdlib.h>
int i = 0;

void    sig2(int signum)
{
  /* usleep(30); */
  printf("%d\n", i);
  i = 0;
}

void my_handler(int signum)
{
  i++;
}

int     main()
{
  printf("pid: %d\n", getpid());
  if (signal(SIGUSR1, my_handler) == SIG_ERR)
    {
      printf("rt\n");
      exit(0);
    }
  signal(SIGUSR2, sig2);
  while (1);
}

signal 的行为在平台之间不一致,在某些系统上信号是 one-shot,在其他系统上它是重复的。 Linux,具体来说,使用 System V 行为(除非定义了 _BSD_SOURCE 宏),即 one-shot。处理完信号后,它会重置为 SIG_DFL.

要获得一致的行为,您应该使用 sigaction 而不是可以使用标志设置行为的地方。

您错过了一些信号,这些信号彼此 "on top" 到达,速度太快,应用程序无法处理。

standard says:

If a subsequent occurrence of a pending signal is generated, it is implementation-defined as to whether the signal is delivered or accepted more than once in circumstances other than those in which queuing is required.

... 这是普通 UNIX 信号不需要排队的一种有点晦涩的说法。在大多数实现中,它们没有。例如,如果在处理之前产生了五个 SIGFOO 信号,则只有一个将被挂起,因此应用程序将只接收一个。