Re: Signal handling in multi-threaded applications.



On Jul 10, 3:35 am, Krivenok Dmitry <krivenok.dmi...@xxxxxxxxx> wrote:
Hello!

I know two kind of signals:
1) Asynchronous signals like SIGTERM or SIGINT.
These signals are typically generated using the kill() call.
2) Synchronous signals like SIGSEGV or SIGFPE.
These signals are generated by hardware and delivered to the
thread that caused the HW condition.

I also know about two different approaches to signal handling:
1) Synchronous handling of asynchronous signals using sigwait
system call.
In such a case a dedicated thread is used for calling
sigwait() in a loop.
2) Asynchronous handling of synchronous signals using signal
actions. This is a classic approach to signal handling.
Actions are set using sigaction() function.
However there is a limited set of functions that may be safety
called from within catching functions.
These functions are called "async-signal-safe".

One of "async-signal-safe" functions is sem_post() function.
It allows one to write code like this:

...
sig_atomic_t catched = 0;
sem_t semaphore;
...
sem_init(&semaphore,0,0);
...
int signals_handler(int signo)
{
catched = signo;
sem_post(&semaphore);
return 0;}

...
...
int main()
{
...
// Init all.
...
// Start worker threads.
...
// Signal handling
while(1)
{
sig_wait(&semaphore);

it's not sigwait()?
// What signal has been received?
int signo = catched;
// Restore state.
catched = 0;
switch(signo)
{
case SIGTERM :
logg("SIGTERM received. Exiting.");
exit(-1);
case SIGSEGV :
logg("SIGSEGV received. It's really bad. Exiting.");
exit(-1);
default :
/* Handle other signals */
};
}
return 0;

}

Catching function is called asynchronously, but it consist of only
"async-signal-safe" functions.
In fact, real signal handling (switch operator) is synchronous.

The question arises, is this approach correct?
If so, why should I use sigwait? Why not to handle all signals
asynchronously (regardless of signal type)?

It seems to me that this approach isn't correct and has obvious or
hidden errors.
I'm newbie in UNIX programming and need some help :)

Using sigwait() call in a thread that dedicated to signal handling,
this is because general assumption on which thread will receive the
signal when another thread kill() a signal to the thread
group(process) of POSIX.

At least on many POSIX thread implementation, when another process
kill() a signal to a thread groups, it is random to choose a thread to
be paused to handle the signal, so to make this event determined, a
programming scheme will be block all the async signal in most thread,
but only let one thread unblock it, so the signal will delivered to
this thread.


.