I am trying to write the program, which will stop and continue thread instead of cancel it. I need to know, how can I achieve that?
I want to use pthread_kill() function with SIGSTOP and SIGCONT signals to thread.
#include <pthread.h>
#include <signal.h>
#include <stdio.h>
#include <time.h>
void *threadfunc(){
while(1){
printf("i am thread \n");
sleep(1);
}
}
void main(){
pthread_t thread;
pthread_create(&thread, NULL, threadfunc, NULL);
sleep(2);
pthread_kill(thread, SIGSTOP);
printf("signal sent \n");
sleep(2);
printf("i am main thread \n");
}
My expectation:
Program starts, 2 times "i am thread" printed, pthread_kill sent signal to stop the thread, user see "signal sent" and "i am main thread".
Actual results:
Programs starts, 2 times "i am thread" printed, pthread_kill sent stop signal and program terminate
There is no one right way to pause and resume a thread.
First, there is no way at all to do it without the cooperation of the code that thread is running. Otherwise, disaster could occur if you pause a thread while it holds a lock that the thread that would resume it needs to acquire before it can resume. So you must have the cooperation of the code the thread you want to pause is running.
With the thread's cooperation, you can do it however you like. You can have an atomic bool that the thread periodically checks. You can just not give the thread work to do if it's designed to pause when it has no work to do.
There's no one right way and it entirely depends on other design decisions. Primarily, it depends on what that code is doing and why you want to pause it.
One other thing that is extremely important: Any time you feel you need to reach into a thread from outside and make it do or not do something, that should be a sign to you that you coded the thread wrong in the first place. A thread should know what work it needs to do and when it needs to not do work by its own design. If something else has to "reach in" intrusively and make it do or not do things, you should re-examine the design decisions that got you to that point.
And to your specific point:
I want to use pthread_kill() function with SIGSTOP and SIGCONT signals to thread.
That couldn't possibly work. What if the thread happens to hold an internal library lock that needs to be acquired to return from pthread_kill? The thread trying to pause it would also pause itself. In any event, SIGSTOP is defined as stopping a process, not a thread.
You cannot use SIGSTOP/SIGCONT signals on threads as they have several major problems:
They are actualy handled by process, not by thread. Even when sent to
thread.
They don't get queued. If you send them faster than handler can receive them, only the first one gets handled. So you can pause thread, loose unpause signal and remain deadlocked because of it.
Luckily there are "realtime signals", which can be used to emulate STOP/CONT behaviour you are looking for. See my proposal here: https://stackoverflow.com/a/68119116/10277365
Related
Hi I'm stuck with this problem and I can't figure out which is the best solution for that:
I have a process with some threads. All the threads have signal masked and only one (SignalHandler) that check if there are pending signals.
while(!shouldEnd){
if(!sigwait(&set, &signum)){
if(signum == SIGINT){
fprintf(stderr, "Ricevuto SIGINT\n");
}
else{
//TODO
}
}
}
Now I would like to terminate even other threads when it receive a SIGINT (for instance). How can I do it properly ? The main problem is that the others thread might be waiting on a condition variable or waiting in a accept() (for socket connections). I think would be a good thing put a variable like "shouldEnd" and set it to 1 when threads should stop working. Is that a good idea ? And what about the waiting one ? Mostly for the one waiting for a socket connection ?
So, first and foremost, we don't know what you're using for threads. You might consider using libBoost for this, as it will make your life easier with RAII style locks and whatnot.
Anyhow, only the elected thread of your process (typically main(), in most examples), will catch the signal, unless you've enabled signal masking. When you want the threads to shut down cleanly, you just need to:
Wakeup the threads waiting on accept() by modifying your FD set to include a pipe that can also wake up the blocking call.
Simply signal the condvars the other threads are waiting on, and set some sort of mutex-protected boolean/flag to notify the thread that it should exit early (ie: mutexLock()l; bool bExitEarly = true; signal(condVar); mutexUnlock();).
Assuming you spawned the threads as joinable (ie: non-detached), just make sure you have a copy of the pointer to each thread object, and call thread_join() on each of them after you've signaled them to stop. This will ensure that the threads are fully stopped before main() exits. If you don't do this, main() could exit before the threads are done, and just forcibly kill off the threads while they are in the middle of their shutdown logic, which is messy, and could cause your program to crash or worse.
I'm currently writing a program that the main thread is going to create three child threads. These threads are running simultaneously and what I want to do is once one of the child thread is done, I will check if the output is right. If it is, then terminate the other two threads; if not, then throw away this thread's result and wait for the other two threads' result.
I'm creating the three results in the main function with pthread_create. But I do not know how to use join function. If I use join function three times in the main function, it just waits one by one until the three threads are done.
My plan is like this:
int return_value;
main(){
pthread_create(&pid[0], NULL, fun0, NULL);
pthread_create(&pid[1], NULL, fun1, NULL);
pthread_create(&pid[2], NULL, fun2, NULL);
}
fun0(){
...
if( check the result is right ){
return_value = result;
if (pid[1] is running) pthread_kill( pid[1], SIGTERM );
if (pid[2] is running) pthread_kill( pid[2], SIGTERM );
}
fun1() ...
fun2() ...
function 0, 1, and 2 are similar to each other and once one function has the right answer, it will kill the other two threads. However, while running the program, once the pthread_kill is processed, the whole program is terminated, not just one thread. I don't know why.
And I still do not know if there are any other ways to code this program. Thanks for helping me out of this.
The pthread_kill() function is not designed to terminate threads, just like kill() is not designed to terminate processes. These functions just send signals, and their names are unfortunate byproducts of history. Certain signal handlers will cause the process to terminate. Using pthread_kill() allows you to select which thread handles a signal, but the signal handler will still do the exact same thing (e.g., terminate the process).
To terminate a thread, use pthread_cancel(). This will normally terminate the thread at the next cancellation point. Cancellation points are listed in the man page for pthread_cancel(), only certain functions like write(), sleep(), pthread_testcancel() are cancellation points.
However, if you set the cancelability type of the thread (with pthread_setcanceltype()) to PTHREAD_CANCEL_ASYNCHRONOUS, you can cancel the thread at any time. This can be DANGEROUS and you must be very careful. For example, if you cancel a thread in the middle of a malloc() call, you will get all sorts of nasty problems later on.
You will probably find it much easier to either test a shared variable every now and then, or perhaps even to use different processes which you can then just kill() if you don't need them any more. Canceling a thread is tricky.
Summary
Easiest option is to just test a variable in each thread to see if it should be canceled.
If this doesn't work, my next recommendation is to use fork() instead of pthread_create(), after which you can use kill().
If you want to play with fire, use asynchronous pthread_cancel(). This will probably explode in your face. You will have to spend hours of your precious time hunting bugs and trying to figure out how to do cleanup correctly. You will lose sleep and your cat will die from neglect.
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 have a main thread, which stays in the main function, i.e. I do not create it specifically as in pthread_create, because it's not necessary. This thread opens a file, then creates other threads, waits for them to finish their work (i.e., does the join), cleans up everything (pointers, semaphores, conditional variables and so on...).
Now, I have to apply this code to block SIGINT:
sigset_t set;
int sig;
sigemptyset(&set);
sigaddset(&set, SIGINT);
pthread_sigmask(SIG_BLOCK, &set, NULL);
while (1) {
sigwait(&set, &sig);
switch (sig) {
case SIGINT:
/* handle interrupts */
break;
default:
/* unexpected signal */
pthread_exit((void *)-1);
}
}
and it says You must use the main() function to launch the N+1 threads and wait for their completion. If a SIGINT signal arrives at the program it should be handled by the main thread in order to shutdown the program and its threads a clean way
My doubt is how should I put this code? Is it wrong to put it on a background thread created in main() ? Because I already have a cicle, with an exit flag, that creates and join all the other threads, so I don't understand if this code goes exactly to the main function where all is done/called to initiate the program. If I put it on a thread, with this code and the handler to clean, is this considerated as busy waiting?
"It says"? What says? The homework assignment?
The first thing you should understand about programming with threads and signals is that you have very little control over which thread a signal is delivered to. If your main thread wants to be the one to get the signal, it should block the signal before creating any new threads and possible unblock it after it finishes creating them, to ensure that the signal is not delivered to them.
However, if you're following best practices for signal handlers, it probably doesn't matter which thread handles the signal. All the signal handler should do is set a global flag or write a byte to a pipe (whichever works best to get the main thread to notice that the signal happened. (Note that you cannot use condition variables or any locking primitives from signal handlers!) As in the code fragment in your question, blocking the signal and using sigwait is also possible (be aware, again, that it needs to be blocked in all threads), but most programs can't afford to stop and wait just for signals; they need to wait for condition variables and/or input from files as well. One way to solve this issue is to make a dedicated thread to call sigwait, but that's rather wasteful. A better solution, if you're already using select, would be to switch to pselect that can wait for signals as well as file descriptor events (at the same time).
Rather than asking us for the answers (which would be hard to give anyway without seeing the full program you're trying to make this work with), you'd be much better off trying to really understand the intricacies of signals with threads.
If I have a parent coordinator program and a worker program, but the coordinator program is creating all of the needed worker processes. If I want to implement the alarm() method correctly to kill all of the processes and terminate the program after a certain amount of time.
Is this the correct way to implement it? The current way I have it, it does now print out the message corresponding printf() message for the worker processes being killed.
Note: I implemented the ignoring of interrupt signals so more worker processes could proceed without worry.
int main(int argc, char** argv)
{
signal(SIGINT, sig_ctrl);
signal(SIGALRM, sig_alarm);
alarm(5);
sleep(10);
//rest of program which creates the needed processes
}
void sig_ctrl(int sig)
{
printf("Hold on buddy, you're not terminating this program with CTRL^C.\n");
}
void sig_alarm(int sig)
{
sleep(0);
fflush(stdout);
printf("The alarm is sounding, all worker procceses will be...TERMINATED!");
raise(SIGTERM);
}
There's the easy way, which is arguably the sloppy way, and the hard way.
The easy way involves ensuring that the initial process is the process group leader, that it ignores an appropriate signal (but that its children do not ignore the signal), and then sending the signal to the process group.
The harder way requires a list somewhere of all the child processes, and the parent can then duly send a signal to each of the processes, removing the dead ones from its list.
Your program's problem is that sleep() is usually implemented using the SIGALRM timer, so calling it probably overrides your signal() setting for SIGALRM
$ man 3 sleep
BUGS
sleep() may be implemented using SIGALRM; mixing calls to alarm(2) and
sleep() is a bad idea.
(BTW, The sleep(0) is nonsense too. What are you trying to achieve with that?)
I had the same type of problem in some homework for a unix unit. That is pretty much the solution most people came up with :P