关于条件锁和互斥锁(pthread_cond_t和pthread_mutex_t)的疑问

本文通过测试代码探讨了互斥锁与条件变量的工作原理。作者创建了多个线程并使用条件变量来同步线程操作,测试了信号量触发时线程的行为,并对一些现象提出了疑问。

  这两天考虑互斥锁的原理,做了一些代码测试,反倒越来越迷惑了。

 

 

Test类模拟单例类,为了让多个线程并发,添加了条件锁,在func()不加锁的情况下,i一直等于1,说明多个线程没出现不同步的情况,但出现了一下问题:

      1. 将条件锁加到main中时,即在进程中触发singal,此时线程中的wait依然阻塞,但在另一个单独的线程触发singal时,没有问题。难道这些锁只为线程准备的?

      2. 用pthread_cond_signal(&_cond)时,只能触发一个线程不在等待,系统会调度哪个线程开始工作,其他线程依然wait阻塞,这个应该理解对了,所以用broadcast时才能出发所有线程。

      3. 在static void func()这个静态函数中,初始化一个局部变量的锁,到底有没有作用?是不是非要弄成全局的或成员变量等形式,不能用局部变量呢?这个怎么也试不出来。

      4. 模拟了半天,多个线程阻塞后,接到singal后,同时开始工作,也没有出现i的异常,不解,难道模拟线程同时工作有问题?

 

待解中……

<think> 我们正在讨论pthread_cond_wait互斥锁的关系。 需要明确:pthread_cond_wait函数在等待条件变量时,必须与一个互斥锁配合使用。 关键点: 1. 为什么需要互斥锁? 2. pthread_cond_wait内部如何操作互斥锁? 3. 使用模式(等待条件通知条件)的标准流程。 回答结构: 一、关系概述 二、工作流程详解(包含等待端通知端) 三、为什么必须这样设计(避免竞争条件) 四、典型代码示例 五、常见错误 最后,按照要求提出3-5个相关问题。 </think> ### `pthread_cond_wait` 与互斥锁的协同机制 `pthread_cond_wait(cond, mutex)` 是条件变量的核心操作,必须与互斥锁 (`pthread_mutex_t`) 配合使用,二者构成 **线程同步的黄金组合**。其关系工作原理如下: --- #### 一、工作流程详解(四步原子操作) 1. **解锁互斥锁** ```c pthread_mutex_unlock(mutex); // 立即释放锁 ``` - 允许其他线程获取该锁以修改共享数据 2. **阻塞等待条件信号** ```c // 线程进入休眠状态,直到被 cond 唤醒 ``` - 线程被移出调度队列,不消耗CPU资源 3. **被唤醒后重新加锁** ```c pthread_mutex_lock(mutex); // 尝试重新获取锁 ``` - 唤醒后**不会立即执行**,需等待重新获得互斥锁 4. **返回并执行后续操作** - 在持有锁的状态下检查/操作共享数据 > 🔒 **关键特性**:步骤12是**原子操作**(不会被其他线程打断) --- #### 二、为什么必须绑定互斥锁? | 问题 | 无锁方案 | 绑定互斥锁方案 | |-----------------------|------------------------|--------------------------| | **竞争条件** | 可能错过条件变化通知 | 检查条件与等待是原子操作 | | **虚假唤醒** | 可能导致数据不一致 | 通过循环检查条件避免风险 | | **信号丢失** | 通知可能被忽略 | 通过锁保护条件判断逻辑 | --- #### 三、标准使用范式 ```c // 等待方代码 pthread_mutex_lock(&mutex); while (!condition) { // 必须用循环检查条件 pthread_cond_wait(&cond, &mutex); // 原子操作:解锁→等待→加锁 } // 操作共享资源... pthread_mutex_unlock(&mutex); // 通知方代码 pthread_mutex_lock(&mutex); condition = true; // 修改条件 pthread_cond_signal(&cond); // 唤醒至少一个等待线程 pthread_mutex_unlock(&mutex); ``` --- #### 四、关键注意事项 1. **必须使用循环检查条件** - 避免虚假唤醒(spurious wakeup),如: ```c // 错误写法:if (!condition) while (!condition) // 正确写法 ``` 2. **先解锁后等待** - 若先等待后解锁 → 死锁风险(通知方无法获取锁) 3. **通知方应持锁发送信号** - 防止等待方在 `pthread_cond_wait` 解锁后立即加锁前丢失信号 --- #### 五、常见错误案例 ```c // 错误1:未加锁调用 wait pthread_cond_wait(&cond, &mutex); // 未加锁→UB行为! // 错误2:未循环检查条件 if (!ready) { // 应用while而非if pthread_cond_wait(&cond, &mutex); } // 错误3:通知方未持锁 pthread_cond_signal(&cond); // 未保护条件变量→数据竞争 ```
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值