我正在使用 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);
}
}
定时器函数 void timer(void *)
就像它听起来的那样,我已经包含了几行来打印出它自己的线程 ID。
测试时,看到以下内容:
...
OLD THREAD ID = 6041240 TO BE CANCELLED
NEW THREAD ID = 6046456
...
THREAD ID EXECUTING = 6041240
所以定时器函数没有通过调用pthread_cancel()
来终止?
最佳答案
默认情况下,您的线程是使用 cancel type 创建的PTHREAD_CANCEL_DEFERRED
,这意味着您需要确保您的线程有一个所谓的取消点。也就是说,检查取消请求并对其作出 react 的点。
This page包含保证为取消点的函数列表。示例是一些 sleep()
和 pthread 函数。如果您只需要一个函数来纯粹测试线程是否已被取消,而不需要其他任何东西,您也可以使用 pthread_testcancel()
。
另一种选择是通过使用 pthread_setcanceltype()
将您的线程取消类型设置为 PTHREAD_CANCEL_ASYNCHRONOUS
,这将使您的线程即使没有取消点也可以取消。然而,系统仍然可以自由选择线程何时应该真正被取消,你需要非常小心地确保系统在取消时不会处于不一致的状态(通常意味着避免任何系统调用和类似 - 查看 Async-cancel-safe functions 的列表 - 它很短!)。
一般来说,异步取消应该只用于或多或少的“纯”处理线程,而执行系统调用和类似线程的线程最好通过延迟取消和仔细放置取消点来实现。
还有,只要你不是detaching your thread (通过它的属性创建分离,或者在创建后调用 pthread_detach()
),你需要在定时器线程上调用 pthread_join()
来使确保取消后所有资源都被清理干净。否则,您最终可能会处于没有任何备用线程资源的状态,您无法创建任何新线程。
关于c - pthread_cancel() 函数未能终止线程,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11271616/