Blocking all threads from handling signal except one thread - c

In my application ,I have multiple thread and one of these threads is responsible for catching signals and handling them. My main problem is since the OS picks up one of the threads in the process randomly and deliver to it the signal to handle it. So the thread which is picked up might be not the one which is responsible for handling the signal.
I have to block the signals in the main thread and any new thread will inherit the mask of the main thread, so they won't be able to handle the signals and only the corresponding thread will do that.
So can anyone provide me with a sample code in C, how to do that?
I have already wrote the part related to the keep the thread sleeping and wake it up upon the receipt of a signal, you can find the following stackoverflow - Thread blocked waiting for a signal.

Related

pthread_kill vs pthread_cond_signal for pausing/resuming a thread on a specific point

This request is about PThreads and using conditions or signals to pause/resume a continuous cycle worker thread.
A while ago, I came into this:
https://stackoverflow.com/a/23945651/6421961
Basically, user johnnycrash uses sigwait() to get a thread into a pause state (waiting for external wakening) and pthread_kill(thread_id, USR1) to signal the thread into waking up. He claims it to be faster than using the mutex+condition construct and it appears to be less complex. I am developing a piece of software that would indeed require a thread to sleep until signaled and return to sleep after doing work in an infinite cycle (the eater of a feeder-eater paradigm).
I am using this to have a separate thread waiting for the conclusion of worker threads. In my current implementation, worker threads add their handles to a list protected by a mutex, signal the waiting thread with pthread_kill and finish with pthread_join.
My questions are all related:
How valid is it to actually use pthread_kill()+sigwait() instead of mutex+condition?
In case it is an acceptable solution, what pitfalls/race conditions
should one be aware of?
Would it be better to use pthread_sigqueue() instead of pthread_kill()? Would it actually be able catch signals sent while sigwait() is not running and immediately process them as soon as sigwait() is called?
Last question, derived from some contradicting information I found: Will different threads both paused with sigwait() expecting USR1 be able to be signaled independently, or will only one of them be able to actually catch the signal regardless of which one was signaled?
I will try to answer points 1 and 4.
pthread_kill() + sigqueue() and mutex+condition they both have their own purposes. When you're working with data (i.e. global variable) which is used by multiple threads in that case mutex are more appropriate. But, when you're waiting for an external event (like. network packet) and want to signal your thread based on that event pthread_kill() is more appropriate.
It depends how the signal (USR1) was sent. If it was sent using pthread_kill() or pthread_sigqueue() you can specify which thread you're sending that signal to, the only difference is with pthread_sigqueue() - you can send an additional information with the signal. You can also send signal to specific pid or group-wise signal sending using kill(). So, it largely depends on your need.

Avoiding SIGINT for pthread instances [duplicate]

I am writing a multithreaded program where I want to handle a possible Ctrl-C command from the user to terminate execution. As far as I know there is no guarantee that the main thread, which is able to cancel every working thread, will catch the signal. Is it, therefore, necessary to have a different signal handler to the code of the working thread so that anyone will catch the signal if it arrives, or is there another way to do that with having a signal handler only in the main thread's code?
You can block signals from the calling thread with pthread_sigmask().
And, as the blocked signals are inherited to newly created threads, you can block SIGINT in the main thread, then launch your other threads, and then unblock it in the main thread, if that is preferable.

How sending a signal to a thread in c?

1-Sending unix signals is only possible to a processes, or it is also possible to send signals to threads?
2-Is it possible to send the tid of a thread to a kernel module? How?
3-In what way the kernel module can find the tid of a thread, to send a signal?
4-the thread will have a handler that will run on each signal. If each handler corresponds to a signal, are there any race conditions?
Can communicate a signal to all threads? What happens if all access the handler at a time?
Ad.1 From where do you want to send a signal? You can use kill() to send signal to process and pthread_kill() to send it to thread (but only from process which created thread).
Ad.3. While handling one signal, other pending signals will be queued, so there will be no race conditions. But you need to set non local variables used in handler to atomic (so when interrupt comes setting this variable will not be interrupted) and check which functions are handler safe.
About signals and threads - signal usually comes directly to process (only with pthread_kill you can send signal to thread from user space). If you have multithreaded process and none of thread has this signal blocked, then signal will come to random thread (the one which is running exactly when signal comes). If you block all threads but one, then signal will come to only this one thread.

Handling process exit from within a thread in a multi-threaded application

I have a multithreaded application. The application has the following set of threads:
The main thread that sleeps. All signals are blocked in this thread.
Thread t1 that does all the processing. All signals are blocked in this thread.
A signal handling thread (t2) setup by a third party component that I use. This thread waits only for the SIGINT and SIGKILL signals. all other signals are blocked in this thread.
My own custom signal handling thread (t3).
Now, for handling the process exit, I was sending a SIGUSR1 to my process. The signal would get caught by thread t3. Thread t3 would call the cleanup routine and exit. The problem here is that thread t3 tries to cleanup resources accessed by the other threads. This would result in intermittent crashes.
Obviously, my present solution does not have a graceful process exit handling. My question is how should one go about handling the process exit in such a scenario? How should the signal handling thread go about stopping the remaining threads and then doing a process exit?
Or is there a better way than sending signals (SIGUSR1) for process termination?
My application is written in C and runs on RHEL 5.
Put a mutex on the cleanup routine so two threads don't try to clean up at once. The thread that wants to shut down should acquire the mutex and then tell other threads to shut down (whichever way you normally do that). This way only one thread should ever do the actual cleanup.
void cleanup()
{
pthread_mutex_lock(m);
if (!cleanup_done) {
cleanup_done = 1;
tell_other_threads_to_stop();
wait_for_other_threads_to_finish();
clean_up_common_resources();
}
pthread_mutex_unlock(m);
}
Alternatively you can lock all shared resources permanently, clean them up and terminate the entire process while holding the locks.
One good way to handle signals in a multi-threaded application is to have only one thread wait for signals, all other threads should have signals blocked. Normally, this is the main thread that initializes all components/libraries, creates other threads, waits for signals and terminates the application in an orderly fashion.
It is not clear why your application has threads 1 and 4. Thread 2 can do all the work and handle all signals (should probably be the main thread). Generally, it is not a good idea to let a third party component handle signals, so it may be better to block signals in thread 3.
The standard termination signals an application should handle are SIGINT (sent upon ctrl-c keystroke) and SIGTERM sent by kill <app-pid>.
Your t3 has to cancel t1/t2 and wait for their terminations before calling exit() since race conditions exist here.
Don't be lazy in this situation because there are no other ways.
By the way, since your main() does nothing, you can simply finish it early with an explicit pthread_exit().

Signalling all threads in a process

Without keeping a list of current threads, I'm trying to see that a realtime signal gets delivered to all threads in my process. My idea is to go about it like this:
Initially the signal handler is installed and the signal is unblocked in all threads.
When one thread wants to send the 'broadcast' signal, it acquires a mutex and sets a global flag that the broadcast is taking place.
The sender blocks the signal (using pthread_sigmask) for itself, and enters a loop repeatedly calling raise(sig) until sigpending indicates that the signal is pending (there were no threads remaining with the signal blocked).
As threads receive the signal, they act on it but wait in the signal handler for the broadcast flag to be cleared, so that the signal will remain masked.
The sender finishes the loop by unblocking the signal (in order to get its own delivery).
When the sender handles its own signal, it clears the global flag so that all the other threads can continue with their business.
The problem I'm running into is that pthread_sigmask is not being respected. Everything works right if I run the test program under strace (presumably due to different scheduling timing), but as soon as I run it alone, the sender receives its own signal (despite having blocked it..?) and none of the other threads ever get scheduled.
Any ideas what might be wrong? I've tried using sigqueue instead of raise, probing the signal mask, adding sleep all over the place to make sure the threads are patiently waiting for their signals, etc. and now I'm at a loss.
Edit: Thanks to psmears' answer, I think I understand the problem. Here's a potential solution. Feedback would be great:
At any given time, I can know the number of threads running, and I can prevent all thread creation and exiting during the broadcast signal if I need to.
The thread that wants to do the broadcast signal acquires a lock (so no other thread can do it at the same time), then blocks the signal for itself, and sends num_threads signals to the process, then unblocks the signal for itself.
The signal handler atomically increments a counter, and each instance of the signal handler waits until that counter is equal to num_threads to return.
The thread that did the broadcast also waits for the counter to reach num_threads, then it releases the lock.
One possible concern is that the signals will not get queued if the kernel is out of memory (Linux seems to have that issue). Do you know if sigqueue reliably informs the caller when it's unable to queue the signal (in which case I would loop until it succeeds), or could signals possibly be silently lost?
Edit 2: It seems to be working now. According to the documentation for sigqueue, it returns EAGAIN if it fails to queue the signal. But for robustness, I decided to just keep calling sigqueue until num_threads-1 signal handlers are running, interleaving calls to sched_yield after I've sent num_threads-1 signals.
There was a race condition at thread creation time, counting new threads, but I solved it with a strange (ab)use of read-write locks. Thread creation is "reading" and the broadcast signal is "writing", so unless there's a thread trying to broadcast, it doesn't create any contention at thread-creation.
raise() sends the signal to the current thread (only), so other threads won't receive it. I suspect that the fact that strace makes things work is a bug in strace (due to the way it works it ends up intercepting all signals sent to the process and re-raising them, so it may be re-raising them in the wrong way...).
You can probably get round that using kill(getpid(), <signal>) to send the signal to the current process as a whole.
However, another potential issue you might see is that sigpending() can indicate that the signal is pending on the process before all threads have received it - all that means is that there is at least one such signal pending for the process, and no CPU has yet become available to run a thread to deliver it...
Can you describe more details of what you're aiming to achieve? And how portable you want it to be? There's almost certainly a better way of doing it (signals are almost always a major headache, especially when mixed with threads...)
In multithreaded program raise(sig) is equivalent to pthread_kill(pthread_self(), sig).
Try kill(getpid(), sig)
Given that you can apparently lock thread creation and destruction, could you not just have the "broadcasting" thread post the required updates to thread-local-state in a per-thread queue, which each thread checks whenever it goes to use the thread-local-state? If there's outstanding update(s), it first applies them.
You are trying to synchronize a set of threads.
From a design pattern point of view the pthread native solution for your problem would be a pthread barrier.

Resources