3

I'm learning the pthread_cancel function and testing whether thread would be cancelled when it doesn't reach cancellation point. Thread is created by default attribute and make it running in add loop. But when cancellation request was sent and thread exit immediately. It doesn't reach cancellation point and I think it should not respond to the request immediately.

#include <stdio.h>
#include <pthread.h>
#include <stdlib.h>

void *thread_func(void *arg)
{
    int i;
    int j;
    int k;

    k = 1;

    /* add operation */
    for (i=0; i<1000; ++i) {       
        for (j=0; j<10000;++j) {
             ++k;              // maybe for(z=0; z<10000; ++z) added would 
                               // be better
        }
    }
    return (void *)10;
}

int main(void)
{
    char *retval;
    pthread_t tid;

    if (pthread_create(&tid, NULL, thread_func, NULL) != 0) {                 
        printf("create error\n");
    }

    if (pthread_cancel(tid) != 0) { // cancel thread
        printf("cancel error\n");
    }
    pthread_join(tid, (void **)retval); 
    printf("main thread exit\n");
    return 0;
}
hel
  • 581
  • 10
  • 26
  • I'm sorry. I'm just finding that the add loop will complete immediately without request and maybe it's not a good test. – hel Dec 20 '15 at 02:14
  • Don't use `pthread_cancel`. For a starter on why, see here: http://stackoverflow.com/questions/4760687/cancelling-a-thread-using-pthread-cancel-good-practice-or-bad – John Zwinck Dec 20 '15 at 02:33

2 Answers2

1

To have a "cancellation point" you need to use pthread_setcancelstate() to disable cancellation at the start of your thread function and then enable it when you want. When a new thread is spawned, it has the cancel state "enabled" meaning it can be canceled immediately at any time.

Perhaps more to the point, you probably shouldn't use pthread_cancel() at all. For more on that, see here: Cancelling a thread using pthread_cancel : good practice or bad

Community
  • 1
  • 1
John Zwinck
  • 239,568
  • 38
  • 324
  • 436
  • Yeah, thanks. And I'm testing the property of pthread_cancel. Maybe this function is not a good choice indeed. – hel Dec 20 '15 at 04:18
0

Cancelling a thread never means that it will immediately cancel anything which is running. It would just post a request to that thread. pthread_cancel only cancels a thread at a cancellation point. The list of cancellation points are defined in the man page of pthreads. In the above thread, you don't have any code which is a cancellation point. So the thread will always complete and will never get canceled. You can increase the loop or put a print statement at the last line of your thread and you will see that it is always completing the thread.

But, if you change the below code to add usleep (it is one of the cancellation point as defined in the man pages), you can see that the thread terminates after usleep. Even if you run any number of times, the thread will only get terminated at the cancellation point that is immediately after usleep and not any other point.

#include <stdio.h>
#include <pthread.h>
#include <stdlib.h>
#include <unistd.h>

void *thread_func(void *arg)
{
    int i;
    int j;
    int k;

    k = 1;

    /* add operation */
    for (i=0; i<1000; ++i) {
        printf("Before - %d\n", i);
        usleep(1);
        printf("After - %d\n", i);
        for (j=0; j<10000;++j) {
             ++k;              // maybe for(z=0; z<10000; ++z) added would
                               // be better
        }
        printf("Never - %d\n", i);
    }
    printf("Normal Exit of thread\n");
    return (void *)10;
}

int main(void)
{
    char *retval;
    pthread_t tid;

    if (pthread_create(&tid, NULL, thread_func, NULL) != 0) {
        printf("create error\n");
    }

    usleep(1000);
    if (pthread_cancel(tid) != 0) { // cancel thread
        printf("cancel error\n");
    }
    pthread_join(tid, (void **)retval);
    printf("main thread exit\n");
    return 0;
}
t j
  • 7,026
  • 12
  • 46
  • 66