Say I have a Thread A, which wants to send signals to Threads B, C and D. Can I do something like this.
SendSignalTo( ThreadB, SIGUSR1 );
SendSignalTo( ThreadC, SIGUSR1 );
SendSignalTo( ThreadD, SIGUSR1 );
With SIGUSR1 signal handler, defined differently for Thread B, C and D, like as follows.
void SIGUSR1_Handler_for_ThreadB(...){...}
void SIGUSR1_Handler_for_ThreadC(...){...}
void SIGUSR1_Handler_for_ThreadD(...){...}
And if not, what is the alternative.
You can send a signal to a specific thread using
pthread_kill(), or if you don’t mind being GNU-specific, usingpthread_sigqueue()(which can specify oneintorvoid *the handler can access viainfo->si_value).There is only one signal handler per signal for the process. This means that a specific signal will always call the same handler function, no matter which thread it happens to be. If one thread sets a new signal handler, the signal handler will change for all threads.
However, the workaround is trivial: use a per-thread function pointer to define which function the signal handler should call. Just remember the signal handler limitations — you can only use async-signal safe functions in a signal handler.
The atomic load (
__sync_fetch_and_or()) allows you to trivially change the per-thread handler using a simple atomic store at any point in time, without even blocking the signal. Switching to functionnew_thread_handleris thenThe
__sync_fetch_and_or()and the function switch can both be replaced by one C++11-style__atomic_call, but I don’t have a GCC recent enough yet, so I’m still using the old-style__sync_calls.POSIX also supports real-time signals,
SIGRTMIN+0,SIGRTMIN+1, ..,SIGRTMAX. They have the added benefit that more than one of them can be pending at the same time. They are much better suited for this kind of thing than the traditional signals.