posix threads block signal and unblock posix threads block signal and unblock multithreading multithreading

posix threads block signal and unblock


Is there a way to block certain signals and unblock other signals in the same set?

With pthread_sigmask, you can choose to either:

  • add a set of signals to the set of blocked signals, using the constant SIG_BLOCK
  • remove a set of signals to the set of blocked signals, using the constant SIG_UNBLOCK
  • define the set of signals to be blocked, using the constant SIG_SET

In other words, there's a current set of blocked signals for the thread, and you can modify it as specified above, one operation at a time.

The important point is that newly created threads inherit the signal mask of the creating thread, so you can set the mask of the new thread right before creating it, or in the function that the new thread will run, at your convenience.

Regarding your example, I suppose that you are trying to have printer_thread1 block SIGUSR2 and SIGALRM, and have printer_thread2 block SIGUSR1 and SIGALRM, and have the main thread block SIGUSR1 and SIGUSR2, so that each thread can send a signal that will be caught by a single thread (without the code of print, f1 and f2, it's impossible to know for sure what is your intent in your example).

You should be able to achieve that by the following code:

sigset_t set;pthread_t printer_thread1, printer_thread2;// Block signal SIGUSR1 & SIGALRM in printer_thread1sigemptyset(&set);sigaddset(&set, SIGUSR1);sigaddset(&set, SIGALRM);pthread_sigmask(SIG_SET, &set, NULL);pthread_create(&printer_thread1, NULL, print, (void *)&f1);// Block signal SIGUSR2 & SIGALRM in printer_thread2sigaddset(&set, SIGUSR2);sigaddset(&set, SIGALRM);pthread_sigmask(SIG_SET, &set, NULL);pthread_create(&printer_thread2, NULL, print, (void *)&f2);// Block signal SIGUSR1 & SIGUSR2 in the main threadsigemptyset(&set);sigaddset(&set, SIGUSR1);sigaddset(&set, SIGUSR2);// Listen to signal SIGALRMpthread_sigmask(SIG_SET, &set, NULL);bool tl = true;while(1){    if(tl)    {        // thread1 does something        kill(pid, SIGUSR1);        // main thread waits for SIGALRM        sigwait(&set, &sig);        tl = !tl;    }    else    {        // thread2 does something        kill(pid, SIGUSR2);        // main thread waits for SIGALRM        sigwait(&set, &sig);        tl = !tl;    }}

see these man pages :

for further details.


I think what you want to do here is

// Block signal SIGUSR1 in this threadsigemptyset(&set);sigaddset(&set, SIGUSR1);pthread_sigmask(SIG_BLOCK, &set, NULL);// Listen to signal SIGALRMsigemptyset(&set);sigaddset(&set, SIGALRM);pthread_sigmask(SIG_UNBLOCK, &set, NULL);

The set is only used to tell it what to block or unblock. Once passed to the command, you are free to reset it and build up another signal mask. If you skip the sigemptyset, the set will still contain SIGUSR1, which will subsequently be unblocked again. Well, I think that is how it works, at least - it has been a long time since I used signals.