I've got a multithreaded server (using POSIX threads), with one thread for each persistent connection. In one of the threads the other end of the connection closes, resulting in a SIGPIPE being delivered. Is there a (preferably portable) to determine which thread (and so which connection) this happened for so I can have my signal handler either do the thread/connection cleanup work itself or set a flag so that the main and worker thread respectively see that they need to do it later?
EDIT: I'm wondering if I could perhaps use &errno, store it in a global array and associate it with the server's identifier for the thread, and then search for &errno in the signal handler. Would the thread's specific errno be visible to the signal handler? Is my understanding of how the threadsafe errno works even in the ballpark?
The POSIX signal implementation ensures that if a process is already. handling a signal, other incoming signals are suspended until the. handler returns.
A process-directed signal may be delivered to any one of the threads that does not currently have the signal blocked. If more than one of the threads has the signal unblocked, then the kernel chooses an arbitrary thread to which to deliver the signal. Save this answer.
A signal mask is associated with each thread. The list of actions associated with each signal number is shared among all threads in the process. If the signal action specifies termination, stop, or continue, the entire process, thus including all its threads, is respectively terminated, stopped, or continued.
As mentioned earlier, a thread inherits its signal mask from the thread which creates it. The main() function sets the signal mask to block all signals, so all threads created after this point will have all signals blocked, including the signal-handling thread.
I don't think so, no. A better solution for multithreaded servers is to suppress the SIGPIPE
signal (by calling signal(SIGPIPE, SIG_IGN)
as part of the program's startup routine) and then have the thread deal with the error value (-1/EPIPE) returned by send()
instead.
Signals and multithreading don't mix well.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With