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.
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.
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.
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.
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().
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.