pthread多线程学习笔记五条件变量3使用之当wait遇到pthread_cancel

pthread_cond_wait,pthread_cond_timewait是被实现为取消点的,取消点的含义是如果该线程是可取消的,那么当到达取消点的时候,该线程会取消掉并返回。

先看一个例子:

#include <stdio.h>

#include <pthread.h>

#include <unistd.h>

pthread_mutex_t mutex;

pthread_cond_t cond;

void *child1(void *arg)

{

/*pthread_cleanup_push(pthread_mutex_unlock, &mutex);*/

while (1) {

printf("thread 1 get running\n");

printf("thread 1 pthread_mutex_lock returns %d\n",pthread_mutex_lock(&mutex));

pthread_cond_wait(&cond,&mutex);

printf("thread 1 conditional applied\n");

pthread_mutex_unlock(&mutex);

sleep(5);

}

/*pthread_cleanup_pop(0);//comment 2*/

}

void *child2(void *arg)

{

while (1) {

sleep(3); //comment 3

printf("thread 2 get running.\n");

printf("thread 2 pthread_mutex_lock returns %d\n",pthread_mutex_lock(&mutex));

pthread_cond_wait(&cond,&mutex);

printf("thread 2 conditional applied\n");

pthread_mutex_unlock(&mutex);

sleep(1);

}

}

int main(void)

{

int tid1,tid2;

printf("conditional variable test\n");

pthread_mutex_init(&mutex,NULL);

pthread_cond_init(&cond,NULL);

pthread_create(&tid1, NULL, child1, NULL);

pthread_create(&tid2, NULL, child2, NULL);

do {

sleep(2);//comment 4

pthread_cancel(tid1);//comment 5

sleep(2);//comment 6

pthread_cond_signal(&cond);

}while(1);

sleep(100);

pthread_exit(0);

}

如果注释掉的部分不放开的话,线程2会一直停在那里,即使主线程不断的去signal。

原因是:

ß pthread_cond_wait ()和pthread_cond_timedwait()都被实现为取消点,因此,在该处等待的线程将立即重新运行,在重新锁定mutex后离开 pthread_cond_wait(),然后执行取消动作。也就是说如果pthread_cond_wait()被取消,mutex是保持锁定状态的,因而需要定义退出回调函数来为其解锁。

好了,其实要说明的就是上面这句话。