For pthread, How to kill child thread from the main thread

72,359

Solution 1

It is possible to "cancel" a thread using pthread_cancel. However, this isn't typically best practice though under extreme circumstances like a SEGFAULT it may be conisdered a reasonable approach.

Solution 2

In general, you don't really want to violently kill a child thread, but instead you want to ask it to terminate. That way you can be sure that the child is quitting at a safe spot and all its resources are cleaned up.

I generally do this with a small piece of shared state between parent and child to allow the parent to communicate a "quit request" to each child. This can just be a boolean value for each child, protected by a mutex. The child checks this value periodically (every loop iteration, or whatever convenient checkpoints you have in your child thread). Upon seeing "quit_request" being true, the child thread cleans up and calls pthread_exit.

On the parent side, the "kill_child" routine looks something like this:

acquire shared mutex
set quit_request to true 
pthread_join the child 

The pthread_join may take some time, depending on how frequently the child checks its quit request. Make sure your design can handle whatever the delay may be.

Solution 3

You should send SIG_TERM to each of your threads, using

  int pthread_kill(pthread_t thread, int sig);

A quick way to get rid of all threads (besides the main) is to fork() and keep going with the child.
Not hyper clean...

  if (fork()) exit(0); // deals also with -1...

Solution 4

You can use a global variable for the entire program.

int _fCloseThreads;

Set it to 1 when you want the threads to quit execution. Have the threads check that variable in their "loop" and nicely quit when it is set to 1. No need to protect it with a mutex.

You need to wait for the threads to quit. You can use join. Another way is to increment a counter when a thread enters its thread proc and then decriment the counter when it exits. The counter would need to be a global of sorts. Use gcc atomic ops on the counter. The main thread, after setting fCloseThreads, can wait on the counter to go to zero by looping, sleeping, and checking the count.

Finally, you might checkout pthread_cleanup_push and pop. They are a model for allowing a thread to cancel anywhere in its code (uses a longjump) and then call a final cleanup function before exiting threadproc. You basicly put cleanup_push at the top of your threadproc and cleanup_pop at the bottom, create an unwind function, and then at certain cancelation points a thread canceled by a call to pthread_cancel() will longjump back to threadproc and call the unwind function.

Share:
72,359
terry
Author by

terry

Updated on July 09, 2022

Comments

  • terry
    terry almost 2 years

    I use pthread_create to create several child threads. At a time, the main thread wants to kill all child threads or there will be segment falut. Which function should I use to finish that? I searched the answer from google and got function like pthread_kill. But I did not know which signal should I send to the child thread to kill them. My running environment is RHEL 5.4 and programming language is C.

  • Bernie Habermeier
    Bernie Habermeier almost 11 years
    While it's generally good practise to acquire a mutex before modifying any memory that is shared between threads, the fact that this is a single flag that is getting checked for non-zero (or false) status, means that you don't really need to grab a mutex. In this case, there really isn't much that can go wrong from a data coherency perspective.
  • dshepherd
    dshepherd almost 9 years
    @Brent: This question shows an example where even a single flag written once can lead to a race condition after complier optimisations.
  • darnir
    darnir almost 8 years
    Why is pthread_cancel not considered best practice? And if it is not best practice, what is?
  • Benjamin Crawford Ctrl-Alt-Tut
    Benjamin Crawford Ctrl-Alt-Tut over 4 years
    What happens if the child thread terminates before the call to pthread_join? Doesn't the thread need to be guaranteed to be alive when it is joined?