views:

1224

answers:

3

I am writing a program, with a master thread and some worker threads, and I would like to get the signal handling right. My problem is the following :

Master thread starts and do all allocation

Master thread sets a SIGINT signal handler

Master threads start worker threads. worker threads don't need special cleanup, however they can be sleeping on system call or semaphore.

When SIGINT is received, my understanding is that only one thread receives it. So if thread are sleeping on system call or semaphore, they wont be waked up, and I won't be able to pthread_join my worker threads and do all the necessary cleanup in my master thread.

Can the following signal handler resolve my problem ?

void term(int sig)
{
    g_do_cleanup = 1;
    pthread_kill(worker_1_id, some_other_signal);
    ...
    pthread_kill(worker_2_id, some_other_signal);
}

What I expect is that upon receiving SIGINT, all thread will be signaled with another signal, get out of their blocking call, see the g_do_cleanup flag and gracefully exit.

Any comment or link on how to do this properly is welcome.

Edit : I am NOT looking for a way to wakeup multiple thread waiting on a particular condition, so I don't think the pthread_cond_signal approach is what I am looking for. What I want is :

  • Find a way that all thread that are blocked on a blocking call returns from these calls.
  • Or kill all threads except for the main one.
+2  A: 

It sounds to me like what you want is a pthread condition variable, so that you can wake any number of multiple threads by singalling one "event" from your master thread.

See the man pages for PTHREAD_COND_DESTROY and PTHREAD_COND_BROADCAST for more information.

T.E.D.
Yeah. Most people use pthread or the Win32 / MFC implementations for doing threads
Kieveli
No, I don't think it is ok, because it would not wake me up from a blocking select call, or a sem_wait call.Maybe I could replace my semaphores with a pthread_condition, but the semaphore abstraction really fits my synchronisation model.
shodanex
+2  A: 

Your plan seems fine. You are forcing one thread to handle system signals. You'll need to mask the signals except some-other-signal in your worker threads with pthread-sigmask().

I think I would go with a separate thread to handle the process signal rather than master. Have it wait forever on a semaphore or sigwait() or whatever while waiting to run the signal handler. Move the pthread-kill code out of the signal handler. Just set the switch and have the signal-waiting thread send the other_signal to the worker threads and exit itself.

Duck
Using signals to communicate between threads is the wrong approach. many thread libraries don't even work with signals. It's much better to use the tread synchronization mechanisms provided by the thread library like the mentioned condition variables.
lothar
Signals are primitive and far from ideal but his library obviously supports them or he wouldn't be asking. He's not doing anything that hasn't been done successfully many times.
Duck
This not so about thread communication, but about thread termination. pthread_cancel + a signal handling thread might work
shodanex
+3  A: 
Nikolai N Fetissov