stcheng
stcheng

Reputation: 141

How pthread returns the fastest result and terminates the slower ones?

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.

Upvotes: 1

Views: 339

Answers (1)

Dietrich Epp
Dietrich Epp

Reputation: 213338

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

  1. Easiest option is to just test a variable in each thread to see if it should be canceled.

  2. If this doesn't work, my next recommendation is to use fork() instead of pthread_create(), after which you can use kill().

  3. 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.

Upvotes: 5

Related Questions