About the ambiguous description of sigwait()

前端 未结 2 502
臣服心动
臣服心动 2020-12-09 04:38

If no signal in set is pending at the time of the call, the thread shall be suspended until one or more becomes pending. The signals defined by s

2条回答
  •  甜味超标
    2020-12-09 04:48

    Every process has what's called a signal mask associated with it, which defines the set of signals which are blocked. The signal mask can be queried or set with setprocmask(2) (for single-threaded code) and pthread_sigmask(3) (for multithreaded code).

    Whenever a signal is raised (either explicitly via kill(2) or raise(3), or via some other mechanism such as a segmentation fault raising SIGSEGV), the signal is checked against the current signal mask. If the signal is not blocked, then it is acted upon immediately: the corresponding signal handler is called if set, otherwise the default action (typically exiting with abnormal status or ignoring it) is run. If the signal is blocked by the signal mask, then the state of the signal is set to pending, and the program continues execution.

    So consider the following example program:

    #include 
    #include 
    
    void on_sigusr1(int sig)
    {
      // Note: Normally, it's not safe to call almost all library functions in a
      // signal handler, since the signal may have been received in a middle of a
      // call to that function.
      printf("SIGUSR1 received!\n");
    }
    
    int main(void)
    {
      // Set a signal handler for SIGUSR1
      signal(SIGUSR1, &on_sigusr1);
    
      // At program startup, SIGUSR1 is neither blocked nor pending, so raising it
      // will call the signal handler
      raise(SIGUSR1);
    
      // Now let's block SIGUSR1
      sigset_t sigset;
      sigemptyset(&sigset);
      sigaddset(&sigset, SIGUSR1);
      sigprocmask(SIG_BLOCK, &sigset, NULL);
    
      // SIGUSR1 is now blocked, raising it will not call the signal handler
      printf("About to raise SIGUSR1\n");
      raise(SIGUSR1);
      printf("After raising SIGUSR1\n");
    
      // SIGUSR1 is now blocked and pending -- this call to sigwait will return
      // immediately
      int sig;
      int result = sigwait(&sigset, &sig);
      if(result == 0)
        printf("sigwait got signal: %d\n", sig);
    
      // SIGUSR1 is now no longer pending (but still blocked).  Raise it again and
      // unblock it
      raise(SIGUSR1);
      printf("About to unblock SIGUSR1\n");
      sigprocmask(SIG_UNBLOCK, &sigset, NULL);
      printf("Unblocked SIGUSR1\n");
    
      return 0;
    }
    

    Output:

    SIGUSR1 received!
    About to raise SIGUSR1
    After raising SIGUSR1
    sigwait got signal: 30
    About to unblock SIGUSR1
    SIGUSR1 received!
    Unblocked SIGUSR1
    

提交回复
热议问题