首页 > 解决方案 > 它是一种在c语言中挂起相同类型信号的方法吗?

问题描述

当另一个相同类型的信号在处理程序中时,我真的需要使信号挂起。

假设 SIGUSR2 在处理程序中,而 SIGUSR1 是 sa_mask 的成员。如果现在进程收到 SIGUSR1,它将被阻塞并在 SIGUSR2 从处理程序退出后交付,这是合理的。

但是,如果进程在处理程序中处理另一个 SIGUSR2 时收到 SIGUSR2,则第二个信号将永远被忽略。

我希望 SIGUSR2 被挂起并稍后交付。我怎样才能做到这一点?

注意:以下代码只是两个示例,如果您理解我的问题,则无需阅读它们

第一种情况:孩子向父母发送两个信号(SIGUSR1 和 SIGUSR2)。当 SIGUSR1 在处理程序中时, SIGUSR2 将被挂起并稍后交付:

    #define MAXCHILD 1
    void handler1(int signo)
      {
        switch(signo)
        {
          /* handling SIGUSR1 takes one second
          during this time if SIGUSR2 will be blocked on delivery. */
          case SIGUSR1:
          write(1,"SIGUSR1 received \n",strlen("SIGUSR1 received \n"));
          sleep(5);
          break;
          case SIGUSR2:
          write(1,"SIGUSR2 received \n",strlen("SIGUSR2 received \n"));
          break;
        }
      }
    int main()
    {
      struct sigaction action1;
      sigset_t set1;
      sigemptyset(&set1);
      sigaddset(&set1, SIGUSR2);//adding SIGUSR2 to set1
      sigaddset(&set1,SIGUSR1);
      action1.sa_handler = handler1;
      action1.sa_mask = set1;
      action1.sa_flags = 0;
      int inchild=0;
      sigaction(SIGUSR1,(struct sigaction *) &action1,NULL);
      sigaction(SIGUSR2,(struct sigaction *) &action1,NULL);
      pid_t parent=getpid();
      pid_t pid[MAXCHILD];
      for ( int i=0;i<MAXCHILD;i++)
      {
        pid[i]=fork();
        if( pid[i]==0)
        {
          inchild=1;
          break;
        }
      }
      while(inchild==0);
      if(inchild==1)
      {
        //child sends SIGUSR1 and immediately SIGUSR2 to parent
        kill(parent,SIGUSR1);
        kill(parent,SIGUSR2);
        sleep(1);
      }
      printf("end\n");
      return 0;
    }

上面代码的输出是:

SIGUSR1 received 
end
SIGUSR2 received 

没关系。

但是让我们谈谈第二种情况:孩子向父母发送两个信号(SIGUSR1)。当 SIGUSR1 在处理程序中时,第二个 SIGUSR1 将不会挂起,将永远被忽略:

    #define MAXCHILD 1
    void handler1(int signo)
      {
        switch(signo)
        {
          /* handling SIGUSR1 takes one second
          during this time if SIGUSR2 will be blocked on delivery. */
          case SIGUSR1:
          write(1,"SIGUSR1 received \n",strlen("SIGUSR1 received \n"));
          sleep(5);
          break;
          case SIGUSR2:
          write(1,"SIGUSR2 received \n",strlen("SIGUSR2 received \n"));
          break;
        }
      }
    int main()
    {
      struct sigaction action1;
      sigset_t set1;
      sigemptyset(&set1);
      sigaddset(&set1, SIGUSR2);//adding SIGUSR2 to set1
      sigaddset(&set1,SIGUSR1);
      action1.sa_handler = handler1;
      action1.sa_mask = set1;
      action1.sa_flags = 0;
      int inchild=0;
      sigaction(SIGUSR1,(struct sigaction *) &action1,NULL);
      sigaction(SIGUSR2,(struct sigaction *) &action1,NULL);
      pid_t parent=getpid();
      pid_t pid[MAXCHILD];
      for ( int i=0;i<MAXCHILD;i++)
      {
        pid[i]=fork();
        if( pid[i]==0)
        {
          inchild=1;
          break;
        }
      }
      while(inchild==0);
      if(inchild==1)
      {
        //child sends SIGUSR1 and immediately SIGUSR1 to parent
        kill(parent,SIGUSR1);
        kill(parent,SIGUSR1);
        sleep(1);
      }
      printf("end\n");
      return 0;
    }

我希望输出是:

SIGUSR1 received
end
SIGUSR1 received

但输出是:

SIGUSR1 received
end

这表明第二个信号已被永远忽略。

发送两个相同类型的信号时如何达到预期结果?我只是希望能够将第二个信号作为待处理信号,有没有办法做到这一点?

根据这个链接,没有办法做到这一点,但我希望有人提供一种虚假的方式来做到这一点,或者至少模拟它(但我希望 write() 函数保留在处理程序中)。

标签: clinuxmultiprocessingsignal-processing

解决方案


推荐阅读