Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

pthread_cancel() function failed to terminate a thread

I'm using pthread_create() and pthread_cancel() functions to create a multithreaded program, but I noticed that pthread_cancel() did not really terminate the thread it was supposed to.

void check(void *param){
    header_t *Bag = (header_t *) param;
    pthread_t timer_thread;
    while(true){
        if(Bag->size && TIMER_OFF){
            pthread_create(&timer_thread, NULL, (void *) &timer, (void *) Bag);
            printf("\nCREATE THREAD ID = %d\n", timer_thread);
            // ADD
        }
        else if(!TIMER_OFF && Bag->size >= 2 && Bag->next->time <= CURRENT_APT_TIME && CRRENT_TAG != Bag->next->tag){
            printf("\nOLD THREAD ID = %d TO BE CANCELLED\n", timer_thread);
            pthread_cancel(timer_thread);
            pthread_create(&timer_thread, NULL, (void *) &timer, (void *) Bag);
            printf("\nNEW THREAD ID = %d\n", timer_thread);
            // Replace
        }
        Sleep(1);
    }
}

timer function void timer(void *) is exactly what it sounds like, and I've included couple of lines to print out the thread ID of itself.

When tested, the following was seen:

...

OLD THREAD ID = 6041240 TO BE CANCELLED

NEW THREAD ID = 6046456

...

THREAD ID EXECUTING = 6041240

So the timer function was not terminated by calling pthread_cancel()?

like image 381
Ryan K Avatar asked Jun 30 '12 05:06

Ryan K


People also ask

How do I cancel a thread on Pthread?

pthread_cancel() in C with example pthread_cancel() = This function cancel a particular thread using thread id. This function send a cancellation request to the thread.

How a thread can be terminated?

A thread automatically terminates when it returns from its entry-point routine. A thread can also explicitly terminate itself or terminate any other thread in the process, using a mechanism called cancelation.

What is the return value of pthread_cancel?

RETURN VALUEIf successful, the pthread_cancel() function returns zero. Otherwise, an error number is returned to indicate the error.

Is pthread_exit necessary?

You are not required to call pthread_exit . The thread function can simply return when it's finished. From the man page: An implicit call to pthread_exit() is made when a thread other than the thread in which main() was first invoked returns from the start routine that was used to create it.


1 Answers

By default your thread is created with the cancel type PTHREAD_CANCEL_DEFERRED, which means that you need to make sure that your thread has a so-called cancellation point. That is, a point where cancel requests are checked and reacted upon.

This page contains a list of functions that are guaranteed to be cancellation points. Examples are some of the sleep() and pthread functions. You can also use pthread_testcancel() if you just need a function to purely test whether the thread has been canceled, and nothing else.

Another option is to set your threads canceltype to be PTHREAD_CANCEL_ASYNCHRONOUS, by using pthread_setcanceltype(), which will make your thread cancelable even without cancellation points. However, the system is still free to choose when the thread should actually be canceled, and you'll need to take great care to make sure that the system isn't left in an inconsistent state when cancelled (typically means avoiding any system calls and similar - see the list of Async-cancel-safe functions - it's short!).

In general, asynchronous cancellation should only be used for more or less "pure" processing threads, whereas threads performing system calls and similar are better implemented with deferred cancellation and careful placement of cancellation points.

Also, as long as you are not detaching your thread (by either creating it detached through its attribute, or by calling pthread_detach() after it is created), you will need to call pthread_join() on the timer thread to make sure that all resources are cleaned up after canceling it. Otherwise you might end up in a state without any spare threading resources, where you cannot create any new threads.

like image 180
sonicwave Avatar answered Nov 03 '22 00:11

sonicwave