pthread多线程同步疑问:thread2持锁wait后thread1为何能加锁?
pthread多线程同步疑问解答
一、为什么thread2调用pthread_cond_wait后,thread1能成功获取互斥锁?
你误解了pthread_cond_wait的行为,它并非仅让线程阻塞,而是原子性地完成两个关键操作:
- 自动释放传入的互斥锁
mutex - 阻塞当前线程,等待条件变量的唤醒信号
所以当thread2执行到pthread_cond_wait(&cond,&mutex);时,已经主动释放了之前锁住的mutex,此时thread1调用pthread_mutex_lock(&mutex)自然能成功获取锁,完全符合手册描述。
当thread1调用pthread_cond_signal(&cond)后,thread2会被唤醒,此时它会重新获取mutex锁,之后才会继续执行printf("thread2: wait 2 %d\n", __LINE__);后续代码。
二、pthread_cond_signal的作用,以及能否用额外互斥锁替代?
1. pthread_cond_signal的核心作用
它用于通知等待在条件变量上的线程:特定条件已满足,让阻塞的线程唤醒并重新检查条件。
条件变量的设计是为了解决「线程需要等待某个条件成立」的场景(比如生产者-消费者模型中,消费者等待队列非空),优势在于:
- 避免线程忙等(无需循环加锁检查条件,节省CPU资源)
- 保证「条件检查+等待」的原子性,彻底规避竞态条件
2. 无法用额外互斥锁替代
如果试图用额外互斥锁在signal位置加锁、wait位置解锁,会引发诸多问题:
- 竞态条件:thread2解锁额外互斥锁后开始等待,若此时thread1还未加锁,条件已满足,thread2会错过该变化,持续阻塞。
- CPU浪费:线程需不断加锁轮询条件,无法高效休眠,占用冗余CPU资源。
- 逻辑混乱:互斥锁的核心是保护共享资源的互斥访问,强行用于条件通知会让代码逻辑复杂且极易出错。
完整测试代码
#include <pthread.h> #include <stdio.h> #include <stdlib.h> pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;/*初始化互斥锁*/ pthread_cond_t cond = PTHREAD_COND_INITIALIZER;/*初始化条件变量*/ void *thread1(void *); void *thread2(void *); int i=1; int main(void) { pthread_t t_a; pthread_t t_b; pthread_create(&t_a,NULL,thread1,(void *)NULL);/*创建线程t_a*/ pthread_create(&t_b,NULL,thread2,(void *)NULL); /*创建线程t_b*/ pthread_join(t_a, NULL);/*等待线程t_a结束*/ pthread_join(t_b, NULL);/*等待线程t_b结束*/ pthread_mutex_destroy(&mutex); pthread_cond_destroy(&cond); exit(0); } void *thread1(void *junk) { for(i=1;i<=6;i++) { printf("djh: Line: %d, i = %d\n", __LINE__, i); pthread_mutex_lock(&mutex);/*锁住互斥量*/ printf("thread1: lock %d\n", __LINE__); if(i%3==0){ printf("thread1:signal 1 %d\n", __LINE__); pthread_cond_signal(&cond);/*条件改变,发送信号,通知t_b线程*/ printf("thread1:signal 2 %d\n", __LINE__); printf("%s will sleep 1s in Line: %d \n", __FUNCTION__, __LINE__); sleep(1); } pthread_mutex_unlock(&mutex);/*解锁互斥量*/ printf("thread1: unlock %d\n", __LINE__); printf("%s will sleep 1s in Line: %d \n\n", __FUNCTION__, __LINE__); sleep(1); } } void *thread2(void *junk) { while(i<6) { printf("djh: Line: %d, i = %d\n", __LINE__, i); pthread_mutex_lock(&mutex); printf("thread2: lock %d\n", __LINE__); if(i%3!=0){ printf("thread2: wait 1 %d\n", __LINE__); pthread_cond_wait(&cond,&mutex);/*解锁mutex,并等待cond改变*/ printf("thread2: wait 2 %d\n", __LINE__); } pthread_mutex_unlock(&mutex); printf("thread2: unlock %d\n", __LINE__); printf("%s will sleep 1s in Line: %d \n\n", __FUNCTION__, __LINE__); sleep(1); } }
内容的提问来源于stack exchange,提问作者Gerrie
相关产品推荐
相关产品推荐

