代码之家  ›  专栏  ›  技术社区  ›  raph77777

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

  •  3
  • raph77777  · 技术社区  · 8 年前

    我对这段代码有问题。我有一个“服务器”和一个“客户端”。服务器等待 SIGUSR1 从客户端。但当我发送 信号1 在一个循环中,服务器不会处理每个信号! 我愿意 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);
    }
    
    2 回复  |  直到 8 年前
        1
  •  5
  •   pilcrow    8 年前

    您丢失了一些信号,这些信号相互“叠加”,速度太快,应用程序无法处理。

    这个 standard says :

    如果生成了后续的未决信号,则实现定义为在需要排队的情况之外的其他情况下,信号是否被传递或接受了不止一次。

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

        2
  •  1
  •   Some programmer dude    8 年前

    的行为 signal 平台之间不一致,在某些系统上信号是一次性的,在其他系统上信号重复。Linux特别使用System V行为(除非 _BSD_SOURCE 宏被定义),这是一个镜头。处理信号后,它将重置为 SIG_DFL .

    为了获得一致的行为,您应该使用 sigaction 相反,可以使用标志设置行为。