A condition wait (whether timed or not) is a cancellation point.
When the cancelability type of a thread is set to PTHREAD_CAN_CEL_DEFERRED, a side-effect of acting upon a cancellation request while in a condition wait is that the mutex is (in effect) re-acquired before calling the first cancellation cleanup handler. The effect is as if the thread were unblocked, allowed to execute up to the point of returning from the call to pthread_cond_timedwait() or pthread_cond_wait(), but at that point notices the cancellation request and instead of returning to the caller of pthread_cond_timedwait() or pthread_cond_wait(), starts the thread cancellation activities, which includes calling cancellation cleanup handlers.
意思就是在pthread_cond_wait时执行pthread_cancel后,要先在pthread_cleanup handler时要先解锁已与相应条件变量绑定的mutex。这样是为了保证pthread_cond_wait可以返回到调用线程。
测试代码:(试一下把cleanup中的pthread_mutex_unlock(&mutex)注释掉可以发现清理时的问题,不注释掉就是正常的清理)
源代码不知道怎么格式了,以纯文本粘贴了
#include <iostream>
#include <pthread.h>
using namespace std;
pthread_mutex_t mutext;
pthread_cond_t cond;
void cleanup(void *arg)
{
cout<<"cleanup"<<endl;
pthread_mutex_unlock(&mutext);
}
void* ThreadTest(void* para){
pthread_cleanup_push(cleanup, NULL);
pthread_mutex_lock(&mutext);
pthread_cond_wait(&cond, &mutext);
pthread_mutex_unlock(&mutext);
cout<<"test"<<endl;
pthread_cleanup_pop(0);
}
int main() {
pthread_mutex_init(&mutext, NULL);
pthread_t thread1,thread2;
pthread_create(&thread1,NULL,ThreadTest,NULL);
pthread_create(&thread2,NULL,ThreadTest,NULL);
pthread_cancel(thread1);
pthread_cancel(thread2);
pthread_join(thread1,NULL);
pthread_join(thread2,NULL);
return 0 ;
}