7

I wrote a simple multithreaded application in C++11 on Linux platform and I would like to terminate the server and its running threads by sending SIGINT signal.

Obviously my server application uses thread support from C++11 (std::thread etc.). Although I found some support for signal handling in C++11 (std::signal), I couldn't find any support for handling signals in multithreaded environment.

So my question is - is there any way how to handle signals in multithreaded application in C++11 or do I have to rely back on pthreads just because my application needs to deal with signals?

Sergey K.
  • 24,894
  • 13
  • 106
  • 174
Tomas Sedlacek
  • 345
  • 4
  • 11

1 Answers1

1

2.4 Signal Concepts:

At the time of generation, a determination shall be made whether the signal has been generated for the process or for a specific thread within the process. Signals which are generated by some action attributable to a particular thread, such as a hardware fault, shall be generated for the thread that caused the signal to be generated. Signals that are generated in association with a process ID or process group ID or an asynchronous event, such as terminal activity, shall be generated for the process.

...

Signals generated for the process shall be delivered to exactly one of those threads within the process which is in a call to a sigwait() function selecting that signal or has not blocked delivery of the signal.

In the light of the above, in a multi-threaded process a common solution is to block all signals one intends to handle in all threads but one. That one thread would normally handle all process signals and tell other threads what to do (e.g. terminate) and is often the main thread. It easy to block the signals in the main thread before creating other threads, that inherit the signal mask of the parent thread. Once the main thread is done creating child threads and is ready to handle signals it must unblock those.

Unfortunately, C++11 does not provide any means for that. You have to use POSIX functions. Scroll down to Signalling in a Multi-Threaded Process in pthread_sigmask for an example that creates a special signal handling thread. The latter is not necessary if you are using an event loop in the main thread that can handle signals, just unblock the signals before entering the event loop.

Community
  • 1
  • 1
Maxim Egorushkin
  • 131,725
  • 17
  • 180
  • 271
  • What if you only want to rely on standard C++11 functions? Could you set a signal handler with std::signal while creating threads *without* blocking signals and simply let a random thread catch the signal? The signal handler would have to be simple, would need C linkage, and preferably only access a volatile int. But would this be C++11 standard compliant and result in well-defined behavior in a multithreaded environment? – JohnCand Nov 07 '13 at 15:58
  • 1
    @JohnCaC2 Probably not, signals are largely outside of the scope of C++ standard. – Maxim Egorushkin Nov 07 '13 at 16:57
  • 1
    I find it bizarre that the powers to be has left per thread signal masks out of c++11 but adressed the rest of threading in std . Setting up signal handling properly in a multithreaded app is a crucial part of writing enterprise class apps. It smells like a half baked solution to be frank. You are now back to libpthread to do it and end up with an unhealthy mix of std threads and posix threads and hope std uses pthreads to do its thing behind the scene – Waslap Jul 19 '16 at 20:17
  • @Waslap Signals are not portable and the platforms that support signals already have APIs that do the job. Just set the signal mask before creating your threads, so that they inherit it and the job is done (only requires one to understand how signals and threads interact). Alternatively, you can roll up your own sleeves and write a full baked solution proposal. However, I do not feel there is a need for that. – Maxim Egorushkin Jul 21 '16 at 10:31
  • 1
    @Maxim Egorushkin You missed an important part of my moaning: How do you know that the specific per-thread signal mask manipulation you are using is at all compatible with the std:thread implementation without having an intricate knowledge of both ? Linux sigprocmask is explicitly stated to be applicable to single-threaded apps. As such, you have to use pthread_sigmask to change signals masks per threads but how do you know std:thread also uses pthreads ? You can guess so and hope so but can you know it will be compatible ? – Waslap Jul 22 '16 at 08:16
  • @Waslap These things are well-documented, I do not see any practical issue here. – Maxim Egorushkin Jul 22 '16 at 09:54