Assume a multi-threaded application, with a signal handler defined in it.
Now if a signal is delivered to the PROCESS, and signal handler is invoked - My doubt is what happens to other threads during the period signal handler is running. Do they keep running, as if nothing has happened or they are suspended for that period .. or ...?
Also if someone can tell me WHY to justify the answer?
The specification is pretty clear how signals and threads interact:
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.
As the signal is delivered to exactly one thread, other threads are unaffected (and keep running).
The threads are independent: a signal from one thread to a second thread will not affect any of the others. The why is because they are independent. The only reason why it would affect the others is if the signal handler of the thread in question somehow interacts with other threads.
Related
I'm a beginner in Linux and Process signal handling.
Let's say we have a process A and it execute pause() function, we know that puts the current process to sleep until a signal is received by the process.
But when we type ctrl-c, kernel also sends a SIGINT to process A and when A receives the signal, it execute the SIGINT's default handler which is terminating the current process. So my question is:
Does the process A resume first or handler get executed first?
For simplicity, let's assume process A has only a single thread, which is blocking in a pause() call, and exactly one signal gets sent to the process.
Does the process A resume first or handler get executed first?
The signal handler gets executed first, then the pause() call returns.
What if there are multiple signals?
Standard signals are not queued, so if you send say two INT signals to the process very quickly in succession, only one of them is delivered.
If there are multiple signals, the order is unspecified.
What about POSIX realtime signals? (SIGRTMIN+0 to SIGRTMAX-0)
They are just like standard named signals, except they are queued (to a limit), and if more than one of them is pending, they get delivered in increasing numerical order.
If there are both standard and realtime signals pending, it is unspecified which ones get delivered first; although in practice, in Linux and many other systems, the standard signals get delivered first, then the realtime ones.
What if there are multiple threads in the process?
The kernel will pick one thread among those that do not have the signal masked (via sigprocmask() or pthread_sigmask()), and use that thread to deliver the signal to the signal handler.
If there are more than one thread blocking in a pause() call, one of them gets woken up. If there are more than one pending signal, it is unspecified whether the one woken thread handles them all, or if more than one thread is woken up.
In general, I warmly recommend reading the man 7 signal, man 7 signal-safety, man 2 sigaction, man 2 sigqueue, and man 2 sigwaitinfo man pages. (While the links go to the Linux man pages project, each of the pages includes a Conforming To section naming the related standards, and Linux-specific behaviour is clearly marked.)
APUE says about sleep()
This function sleep() causes the calling process to be suspended
until either
The amount of wall clock time speciļ¬ed by seconds has elapsed.
A signal is caught by the process and the signal handler returns.
Does the first case work by sending some specific signal to the process itself? If yes, what is the signal?
alarm() can send signal SIGALARM to the calling process after a specific time period, which is why I wonder if sleep() work in the same way.
Does sleep() change the state of the calling process to the same state as sigsuspend() changes to? Which process state(s) do the two functions change to?
Is it correct that a suspended process can only be waken by a signal? That is the reason why I have the question.
Thanks.
Linux kernel has absolutely no needs in using user signals for change the state of the process. So, a signal emitting is performed only for meet a requirement on a user library's function.
As documentation for sleep function doesn't say that any signal is emitted after the end of the sleep, so the kernel doesn't use signals in that case.
Is it correct that a suspended process can only be waken by a signal?
Yes, user code may awoke sleeping process only by sending signal to it. This is true for most non-runnable process states too.
My application is sometimes terminating from SIGIO or SIGUSR1 signals even though I have blocked these signals.
My main thread starts off with blocking SIGIO and SIGUSR1, then makes 2 AIO read operations. These operations use threads to get notification about operation status. The notify functions (invoked as detached threads) start another AIO operation (they manipulate the data that has been read and start writing it back to the file) and notification is handled by sending signal (one operation uses SIGIO, the other uses SIGUSR1) to this process. I am receiving these signals synchronously by calling sigwait in the main thread. Unfortunately, sometimes my program crashes, being stopped by SIGUSR1 or SIGIO signal (which should be blocked by a sigmask).
One possible solution is to set SIG_IGN handlers for them but this doesn't solve the problem. Their handlers shouldn't be invoked, rather should they be retrieved from pending signals by sigwait in the next iteration of the main program loop.
I have no idea which thread handles this signal in this manner. Maybe it's the init who receives this signal? Or some shell thread? I have no idea.
I'd hazard a guess that the signal is being received by one of your AIO callback threads, or by the very thread which generates the signal. (Prove me wrong and I'll delete this answer.)
Unfortunately per the standard, "[t]he signal mask of [a SIGEV_THREAD] thread is implementation-defined." For example, on Linux (glibc 2.12), if I block SIGUSR1 in main, then contrive to run a SIGEV_THREAD handler from an aio_read call, the handler runs with SIGUSR1 unblocked.
This makes SIGEV_THREAD handlers unsuitable for an application that must reliably and portably handle signals.
The signal mask can be set on a per thread basis, but what about signal handles? If I call sigaction() before creating new threads with pthread_create(), will the new threads get the same signal handler? What if I use sigaction() after pthread_create(), will that change the entire process signal handlers or just the ones of the thread?
There is only ONE signal handler per process. So threads are not relevant in any kind here. The signal handler is called in the thread context which receives the signal. Which thread receives the signal is not specified if multiple threads have not blocked the signal.
You have to take care if multiple threads waits in system calls. Also you have to take care with using timer actions and calls to sleep.
You may also find this answer helpful: POSIX threads and signals
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?
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.