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().
Related
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.
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.
I'm sending a signal from a module in the kernel space to a process. This process has one thread waiting for the signal.
I read the signal manual and it says:
The signal disposition is a per-process attribute: in a multithreaded application, including the disposition of a signal is the same for all threads.
Thus, and according to the manual pthread_sigmask:
http://man7.org/linux/man-pages/man3/pthread_sigmask.3.html
I'm trying to block the signal in the main function of the application by calling:
siginfo_t infoh1;
sigset_t waith1;
sigemptyset(&waith1);
sigaddset(&waith1, SIG_HILO1);
pthread_sigmask( SIG_BLOCK, &waith1, NULL );
Note that the thread is waiting for it in its execution function.
result = sigwaitinfo (&waith1, &infoh1);
The signal is sent, but the thread never receives it (it hangs waiting).
What am I doing wrong? I tested with different codes from different websites without success.
I use signals a lot in my *nix code and I don't think this is a good approach.
I recommend that all threads are set to ignore signals. The main process handles the signal while the thread sits on a mutex/condition. On signal the main process sets a global static flag with the signal type and then notifies the thread which duly checks the flag to see which signal was caught.
It's a safe and easy solution.
Can a pthread, that is detached, die? Can the thread be killed by the OS without stopping the main process?
If you program a detached thread to die after doing its work then it will die. After concluding its work the function can simply end or call pthread_exit.
You can kill a detached thread from another thread by sending a signal with pthread_kill or using a global flag or a form of IPC such as a pipe or message queue. Note the word "killed" is ambiguous between its multiple meanings in both English and programming. The thread needs to be programed to react to whatever notification mechanism is used. For instance a signal handler should be installed for the thread and a non-process-wide signal such as SIGUSR1 sent with pthread_kill or pthread_sigqueue. Lastly pthreads has a cancellation mechanism you can employ using pthread_cancel and related calls. In all these scenarios the point is that the thread must be programmed to handle a request to die gracefully but "detached" does not mean "inaccessible".
If the disposition of a signal is stop, continue or terminate it will affect the process as a whole not a single thread.
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.