条件锁pthread_cond_t

本文详细解释了并发编程中等待线程与激活线程的原理,包括使用pthread库函数pthread_cond_wait和pthread_cond_signal进行线程间的同步与唤醒机制。通过程序示例展示了如何在实际应用中实现线程间的安全交互。
http://egeho123.blogbus.com/logs/10821816.html

2006年09月05日 12:42
说明,
等待线程
1。使用pthread_cond_wait前要先加锁
2。pthread_cond_wait内部会解锁,然后等待条件变量被其它线程激活
3。pthread_cond_wait被激活后会再自动加锁

激活线程:
1。加锁(和等待线程用同一个锁)
2。pthread_cond_signal发送信号
3。解锁
激活线程的上面三个操作在运行时间上都在等待线程的pthread_cond_wait函数内部。

程序示例:

#include <stdio.h>
#include <pthread.h>
#include <unistd.h>

pthread_mutex_t count_lock;
pthread_cond_t count_nonzero;
unsigned count = 0;

void * decrement_count(void *arg) {
pthread_mutex_lock (&count_lock);
printf("decrement_count get count_lock\n");
while(count==0) {
printf("decrement_count count == 0 \n");
printf("decrement_count before cond_wait \n");
pthread_cond_wait( &count_nonzero, &count_lock);
printf("decrement_count after cond_wait \n");
}
count = count -1;
pthread_mutex_unlock (&count_lock);
}

void * increment_count(void *arg){
pthread_mutex_lock(&count_lock);
printf("increment_count get count_lock\n");
if(count==0) {
printf("increment_count before cond_signal\n");
pthread_cond_signal(&count_nonzero);
printf("increment_count after cond_signal\n");
}
count=count+1;
pthread_mutex_unlock(&count_lock);
}

int main(void)
{
pthread_t tid1,tid2;

pthread_mutex_init(&count_lock,NULL);
pthread_cond_init(&count_nonzero,NULL);

pthread_create(&tid1,NULL,decrement_count,NULL);
sleep(2);
pthread_create(&tid2,NULL,increment_count,NULL);

sleep(10);
pthread_exit(0);
}
<think>我们正在讨论pthread_cond_wait和pthread_cond_signal,它们是POSIX线程中用于条件变量的函数。 首先,需要解释这两个函数的作用、用法、注意事项等。 然后,根据规则,在回答的最后提出3-5个相关问题,以“§§相关问题§§”开头,并且禁止换行分散。 现在,开始组织回答: </think>`pthread_cond_wait` 和 `pthread_cond_signal` 是 POSIX 线程库中实现线程同步的核心函数,用于条件变量的操作。以下是详细解析: ### 函数原型 ```c int pthread_cond_wait(pthread_cond_t *cond, pthread_mutex_t *mutex); int pthread_cond_signal(pthread_cond_t *cond); ``` ### 核心机制 1. **`pthread_cond_wait` 工作流程**: - 原子操作:释放 `mutex` 锁 → 线程阻塞 → 被唤醒后重新获取锁 - **必须配合 while 循环** 检查条件(防御虚假唤醒): ```c pthread_mutex_lock(&mutex); while (condition == false) { pthread_cond_wait(&cond, &mutex); } // 执行条件满足后的操作 pthread_mutex_unlock(&mutex); ``` 2. **`pthread_cond_signal` 行为特性**: - 唤醒至少 **一个** 等待该条件变量的线程(唤醒顺序依赖调度策略) - 无等待线程时,信号会 **静默丢弃**(不会累积) - 通常需在持有互斥锁时调用(非强制但推荐) ### 关键区别 | 特性 | `pthread_cond_wait` | `pthread_cond_signal` | |---------------------|------------------------------------------|--------------------------------| | **目的** | 阻塞线程直到条件满足 | 唤醒等待条件的线程 | | **锁操作** | 释放锁 → 阻塞 → 重新获取锁 | 不涉及锁操作(但建议在锁内调用) | | **唤醒范围** | - | 至少唤醒一个线程 | | **虚假唤醒防护** | 必须用 while 循环 | 不涉及 | ### 典型应用场景 **生产者-消费者模型**: ```c // 生产者线程 pthread_mutex_lock(&mutex); buffer[in] = data; // 生产数据 in = (in + 1) % SIZE; pthread_cond_signal(&cond); // 唤醒消费者 pthread_mutex_unlock(&mutex); // 消费者线程 pthread_mutex_lock(&mutex); while (count == 0) { // 缓冲区空 pthread_cond_wait(&cond, &mutex); } data = buffer[out]; // 消费数据 out = (out + 1) % SIZE; pthread_mutex_unlock(&mutex); ``` ### 重要注意事项 1. **死锁风险**: - 调用 `pthread_cond_wait` 前必须持有 `mutex` - 未配对使用可能导致永久阻塞 2. **广播唤醒**: - 需唤醒所有线程时用 `pthread_cond_broadcast()` - 过度使用可能引发"惊群效应" 3. **性能陷阱**: - 条件变量等待/唤醒涉及内核调度(上下文切换开销) - 高频同步场景建议结合无锁队列 4. **优先级反转**: - 低优先级线程持有锁时,可能阻塞高优先级线程 - 可通过优先级继承协议(如 `PTHREAD_PRIO_INHERIT`)缓解
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值