Why is the thread in my program cancelling before reaching of the testcancel function? I exepected thread will be cancelled when testcancel called, but it cancelling immediately with a changing cancelstate to enable.
#include <stdlib.h>
#include <stdio.h>
#include <pthread.h>
#include <unistd.h>
int i = 0;
void proc1()
{
pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, NULL);
for (i = 0; i < 7; i )
{
if (i == 3) {
pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED, NULL);
pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL);
}
if (i == 5) {
pthread_testcancel();
}
printf("I'm still running! %d\n", i);
sleep(1);
}
}
int main(void)
{
pthread_t thread;
pthread_create(&thread, NULL, (void*)proc1, NULL);
sleep(1);
printf("Requested to cancel the thread\n");
pthread_cancel(thread);
pthread_join(thread, NULL);
printf("The thread is stopped\n");
return 0;
}
Result:
I tried to run it without printf (due to printf is cancellation point too) but it didn't solve the problem.
CodePudding user response:
I exepected thread will be cancelled when testcancel called,
This expectation is not correct.
From the phread_cancel spec
Deferred cancelability means that cancellation will be delayed until the thread next calls a function that is a cancellation point.
There is also a link included to check what a cancellation point is:
The following functions are required to be cancellation points by POSIX.1-2001 and/or POSIX.1-2008:
... pthread_testcancel() ... sleep() ...
Each of them will make your thread respond to cancellation.
This means, also this assumption is not fully correct:
but it cancelling immediately with a changing cancelstate to enable.
Instead your thread is cancelled as soon as it calls sleep
in the same iteration when it sets cancel state to enabled. (BTW: Cancel type is deferred by default)
You seem to expect that the thread only checks whether it is cancelled, when it actively queries for cancel state. I don't think this can be done using pthread_cancel
.
Instead you need to introduce some communication mechanism (maybe via sockets) to tell the thread that it shall terminate itself.