pthread_cancel()函数无法终止线程

Rya*_*n K 3 c multithreading pthreads

我正在使用pthread_create()pthread_cancel()函数来创建一个多线程程序,但我注意到它pthread_cancel()并没有真正终止它应该的线程.

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);
    }
}
Run Code Online (Sandbox Code Playgroud)

定时器功能void timer(void *)正是它听起来的样子,我已经包含几行来打印出自己的线程ID.

测试时,发现以下情况:

...

OLD THREAD ID = 6041240 TO BE CANCELLED

NEW THREAD ID = 6046456

...

THREAD ID EXECUTING = 6041240
Run Code Online (Sandbox Code Playgroud)

所以定时器功能没有通过调用终止pthread_cancel()

son*_*ave 6

默认情况下,您的线程是使用取消类型 创建的PTHREAD_CANCEL_DEFERRED,这意味着您需要确保您的线程具有所谓的取消点.也就是说,检查取消请求并作出反应的点.

此页面包含一系列保证为取消点的功能.示例是一些sleep()和pthread函数.pthread_testcancel()如果你只需要一个函数来纯粹测试线程是否被取消,你也可以使用.

另一种选择是PTHREAD_CANCEL_ASYNCHRONOUS通过使用pthread_setcanceltype()将你的线程取消类型设置为,即使没有取消点,也会使你的线程被取消.但是,系统仍然可以自由选择何时实际取消线程,并且您需要非常小心地确保系统在取消时不会处于不一致状态(通常意味着避免任何系统调用和类似 - 请参阅Async-cancel-safe函数列表- 它很简短!).

通常,异步取消应该仅用于或多或少的"纯"处理线程,而执行系统调用的线程和类似的线程更好地通过延迟取消和小心放置取消点来实现.

此外,只要您没有分离您的线程(通过其属性创建分离,或通过pthread_detach()在创建后调用),您将需要调用pthread_join()计时器线程以确保在取消后清除所有资源它.否则,您可能最终处于没有任何备用线程资源的状态,您无法创建任何新线程.