线程互斥和条件同步,pthread_mutex和pthread_cond

本文介绍了一个使用pthread_mutex和pthread_cond实现线程间互斥与条件同步的例子。通过两个线程的合作,确保了全局变量g_value的安全修改与读取,演示了如何避免竞态条件。
线程互斥和条件同步,pthread_mutex和pthread_cond

#include <stdio.h>
#include <stdlib.h>
#include <getopt.h> //getopt_long()头文件位置    
#include <string.h>
#include <unistd.h>
#include <syslog.h>
#include <pthread.h>

void *thread1_function(void *arg);
void *thread2_function(void *arg);
pthread_mutex_t mutex;
pthread_cond_t cond;
int g_value = 0;

int main(int argc, char *argv[])
{
    pthread_t thread1,thread2;

    pthread_mutex_init(&mutex,NULL);
    pthread_cond_init(&cond,NULL);
    if(pthread_create(&thread1,NULL,thread1_function,NULL))
    {
        fprintf(stdout,"thread 1 create failed\n");
    }
 
    if(pthread_create(&thread2,NULL,thread2_function,NULL))
    {
        fprintf(stdout,"thread 2 create failed\n");
    }
 
    pthread_join(thread1,NULL);
    pthread_join(thread2,NULL);
    return 0;
}

void *thread1_function(void *arg)
{
   char i;
   for (i=0; i<9; i++)
   { 
      pthread_mutex_lock(&mutex);
      g_value ++;
      pthread_cond_signal(&cond);
      pthread_mutex_unlock(&mutex);
      sleep(2);
   }
   return NULL;
}
void *thread2_function(void *arg)
{
   char i;
   for (i=0; i<9; i++)
   { 
      pthread_mutex_lock(&mutex);
      pthread_cond_wait(&cond, &mutex);
      printf("g_value is: %d\n", g_value);
      pthread_mutex_unlock(&mutex);
   }
   return NULL;
}


<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); // 未保护条件变量→数据竞争 ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值