Mixing threads and signals [Unix]

On Unix systems, using threads and signals together is a nightmare.

A lot of programmers start out by writing their code under the mistaken assumption that they can set a separate signal handler for each thread; this is not the way things work. You can block or unblock signals on a thread-by-thread basis, but this is not the same thing as having a separate handler per thread.

When it comes to dealing with signals, the best thing you can do is create a thread whose sole purpose is to handle signals for the entire process. This thread should loop calling sigwait(2); this allows it to deal with signals synchronously. You should also make sure that all threads (including the one that calls sigwait) have the signals you are interested in handling blocked. This is easiest to do by blocking these signals before ever creating the threads.

Note, also, that sending signals to other threads within your own process is not a friendly thing to do, unless you are careful with signal masks. For an explanation, see the FAQ entry on asynchronous cancellation.

Finally, don’t combine use of sigwait with installation of signal handlers for the signals you are sigwaiting for.

2 comments on “Mixing threads and signals [Unix]
  1. Josh says:

    That’s not entirely correct — the Linux clone() API which pthreads is built on top of can, in fact, allow separate signal handlers per thread. That’s actually dead useful in a lot of ways.

  2. Robin says:

    man pthread_sigmask

Leave a Reply

Your email address will not be published. Required fields are marked *