Czy używałeś pthread_cleanup_push i pop? Anulowanie za pomocą pthread_cancel nie działa bez nich. Musisz używać ich parami, tak jak to zrobiłem w poniższym przykładzie. jeśli zapomnisz jednego, to nie skompilujesz (fantazyjne makra, jeden ma "{", a drugi ma "}"). Możesz nawet zagnieździć różne poziomy porządków/popów. W każdym razie, ustawiają one punkt skoku długiego, który anuluje skoki, kiedy nastąpi anulowanie (całkiem fajnie). Ponadto, jeśli twój program testowy nie czeka na rozpoczęcie lub zakończenie wątku, możesz nie zauważyć anulowania.
Przykład:
#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;
}
wyjście Program:
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
Wskazówki, jak anulować ciosy z ThreadProc przy unieważnieniu punktu snu() i wykonuje tylko funkcję odwijania().
Cóż, myślę, że popełniłem błąd, sleep() to punkt anulowania ograniczony przez posix.1 – qiuxiafei
Po prostu notatka - 'pthread_kill' nie zabija wątku. Wysyła sygnał do wątku. Jeśli działanie tego sygnału ma na celu zakończenie procesu (np. Domyślna akcja 'SIGTERM' lub działanie odblokowalne' SIGKILL'), to zakończy * cały proces *, a nie docelowy wątek. Naprawdę jedyny czas, gdy 'pthread_kill' jest użyteczny, to jeśli zainstalowałeś przerywnik sygnału i chcesz przerwać blokadę systemu, która jest zablokowana w konkretnym wątku (który byłby potencjalnym rozwiązaniem twojego pytania). –