Вы использовали pthread_cleanup_push и pop?Отмена с помощью pthread_cancel не работает без них.Вы должны использовать их в парах, как я сделал в примере ниже.если вы забудете один, он не будет компилироваться (причудливые макросы, у одного есть '{', а у другого - '}').Вы можете даже вкладывать разные уровни очистки / всплывающих окон.В любом случае, они устанавливают точку прыжка в длину, которая отменяет переходы, когда происходит отмена (довольно круто).Кроме того, если ваша тестовая программа не ожидает запуска или остановки потока, вы можете не заметить отмены.
Пример:
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
static void *ThreadProc(void * arg);
static void unwind(__attribute__ ((unused)) void *arg);
int _fActive = 0;
int main(int argc, char** argv)
{
pthread_t Thread;
int nRet;
nRet = pthread_create(&Thread, NULL, ThreadProc, NULL);
printf("MAIN: waiting for thread to startup...\n");
while (_fActive == 0)
nanosleep(&(struct timespec){ 0, 0}, NULL);
printf("MAIN: sending cancel...\n");
nRet = pthread_cancel(Thread);
printf("MAIN: waiting for thread to exit...\n");
while (_fActive)
nanosleep(&(struct timespec){ 0, 0}, NULL);
printf("MAIN: done\n");
return 0;
}
static void unwind(__attribute__ ((unused)) void *arg)
{
// do some cleanup if u want
printf("THREAD: unwind (all threads, canceled or normal exit get here)\n");
_fActive = 0;
}
static void *ThreadProc(void * arg)
{
pthread_cleanup_push(unwind, arg);
// optional : pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL);
printf("THREAD: Enter Sleep\n");
_fActive = 1;
sleep(1000000);
printf("THREAD: Exit Sleep (canceled thread never gets here)\n");
pthread_cleanup_pop(1);
printf("THREAD: Exit (canceled thread never gets here)\n");
return NULL;
}
Вывод программы:
MAIN: waiting for thread to startup...
THREAD: Enter Sleep
MAIN: sending cancel...
MAIN: waiting for thread to exit...
THREAD: unwind (all threads, canceled or normal exit get here)
MAIN: done
Обратите внимание, как отмена выдувается из ThreadProc в точке отмены sleep () и выполняет только функцию unwind ().