news 2026/4/18 11:03:08

线程同步之条件变量

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
线程同步之条件变量

文章目录

  • 生产者与消费者
    • 问题
    • 挑战
  • 条件变量
    • 特性
    • 函数接口
      • 初始化
      • 等待条件(阻塞)
      • 发送信号
      • 接收信号(带超时的等待)
      • 销毁
    • 应用模板
    • 示例
  • 虚假唤醒
    • 解决虚假唤醒

生产者与消费者

  • 生产者与消费者问题是多线程编程领域中的一个经典问题,主要用来描述一个或多个生产者线程和一个或多个消费者线程共享有限缓冲区资源时的同步问题

问题

  • 问题的核心在于如何保持生产者和消费者之间的协调,确保当缓冲区已满时生产者停止生产,而当缓冲区已空时消费者停止消费,以避免出现资源浪费或死锁的情况
  • 生产者:生成数据,放入共享缓冲区
  • 消费者:从缓冲区取出数据并处理
  • 缓冲区:有限容量的共享资源

挑战

  • 互斥访问:防止同时读写造成数据不一致
  • 同步协调:
    • 缓冲区满时,生产者应等待
    • 缓冲区空时,消费者应等待

条件变量

  • 条件变量是一种线程同步机制,允许线程在某个条件不满足时阻塞等待,当条件满足时被其他线程唤醒

特性

  • 必须与互斥锁配合使用,条件变量本身不提供互斥保护
  • 用于线程间的通信与协调
  • 解决“忙等待”问题,提高效率

修改条件(谓词)必须在互斥锁保护下

函数接口

初始化

#include<pthread.h>// 静态初始化(全局/静态变量)pthread_cond_tcond=PTHREAD_COND_INITIALIZER;// 动态初始化(栈/堆变量)intpthread_cond_init(pthread_cond_t*cond,constpthread_condattr_t*attr);

等待条件(阻塞)

#include<pthread.h>intpthread_cond_wait(pthread_cond_t*cond,pthread_mutex_t*mutex);
  • 执行过程(原子操作):
    • 解锁互斥量 mutex
    • 阻塞线程,等待条件变量 cond 的信号
    • 收到信号后,重新锁定 mutex
    • 返回

发送信号

#include<pthread.h>intpthread_cond_signal(pthread_cond_t*cond);// 唤醒一个等待线程,适合只有一个线程能处理的情况intpthread_cond_broadcast(pthread_cond_t*cond);// 唤醒所有等待线程,适合多个线程都能处理的情况

接收信号(带超时的等待)

intpthread_cond_timedwait(pthread_cond_t*cond,pthread_mutex_t*mutex,conststructtimespec*abstime);intpthread_cond_wait(pthread_cond_t*restrict cond,pthread_mutex_t*restrict mutex);

销毁

intpthread_cond_destroy(pthread_cond_t*cond);
  • 销毁前确保没有线程在等待,确保所有线程都已退出或不再等待

应用模板

pthread_mutex_tmutex=PTHREAD_MUTEX_INITIALIZER;pthread_cond_tcond=PTHREAD_COND_INITIALIZER;intcondition=0;// 条件变量关联的谓词// 等待线程pthread_mutex_lock(&mutex);// 必须用while循环!while(!condition){pthread_cond_wait(&cond,&mutex);}// 执行操作...pthread_mutex_unlock(&mutex);// 通知线程pthread_mutex_lock(&mutex);condition=1;// 修改条件pthread_cond_signal(&cond);// 或 broadcastpthread_mutex_unlock(&mutex);

示例

#include<pthread.h>#include<stdio.h>#include<stdlib.h>#defineBUFFER_SIZE5intbuffer[BUFFER_SIZE];intcount=0;// 当前缓冲区数据数量intin=0;// 生产者插入位置intout=0;// 消费者取出位置pthread_mutex_tmutex=PTHREAD_MUTEX_INITIALIZER;pthread_cond_tnot_empty=PTHREAD_COND_INITIALIZER;// 非空条件pthread_cond_tnot_full=PTHREAD_COND_INITIALIZER;// 非满条件// 生产者void*producer(void*arg){intitem;while(1){item=rand()%1000;// 生产数据pthread_mutex_lock(&mutex);// 缓冲区满则等待while(count==BUFFER_SIZE){pthread_cond_wait(&not_full,&mutex);}// 生产数据buffer[in]=item;in=(in+1)%BUFFER_SIZE;count++;printf("生产者: 生产 %d, 当前数量: %d\n",item,count);// 通知消费者pthread_cond_signal(&not_empty);pthread_mutex_unlock(&mutex);sleep(1);// 模拟生产耗时}returnNULL;}// 消费者void*consumer(void*arg){intitem;while(1){pthread_mutex_lock(&mutex);// 缓冲区空则等待while(count==0){pthread_cond_wait(&not_empty,&mutex);}// 消费数据item=buffer[out];out=(out+1)%BUFFER_SIZE;count--;printf("消费者: 消费 %d, 当前数量: %d\n",item,count);// 通知生产者pthread_cond_signal(&not_full);pthread_mutex_unlock(&mutex);sleep(2);// 模拟消费耗时}returnNULL;}

虚假唤醒

  • 即使没有线程调用pthread_cond_signal()或pthread_cond_broadcast(),等待在条件变量上的线程也可能被唤醒
  • 虚假唤醒的原因:
    • 多处理器系统的实现细节
    • 信号处理中断
    • 条件变量实现的复杂性

解决虚假唤醒

// 错误:使用if可能错过检查pthread_mutex_lock(&mutex);if(count==0){pthread_cond_wait(&cond,&mutex);}// 这里可能count仍然为0!// 正确:使用while确保条件真正满足pthread_mutex_lock(&mutex);while(count==0){pthread_cond_wait(&cond,&mutex);}// 这里count一定不为0
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/4/18 8:48:34

OpenDog V3终极指南:免费开源四足机器人快速入门

OpenDog V3终极指南&#xff1a;免费开源四足机器人快速入门 【免费下载链接】openDogV3 项目地址: https://gitcode.com/gh_mirrors/op/openDogV3 OpenDog V3是一个基于MIT许可证的完整开源四足机器人平台&#xff0c;为机器人技术新手和中级开发者提供了完美的学习实…

作者头像 李华
网站建设 2026/4/18 4:22:42

环境仿真软件:SWAT_(2).环境建模基础

环境建模基础 在环境仿真软件的二次开发中&#xff0c;环境建模是一个至关重要的步骤。环境建模不仅涉及到对自然环境的模拟&#xff0c;还需要考虑人类活动对环境的影响。在本节中&#xff0c;我们将详细介绍环境建模的基本原理和方法&#xff0c;并通过具体的例子来说明如何在…

作者头像 李华
网站建设 2026/4/17 12:39:33

Vosk语音识别工具包:零基础快速上手指南

Vosk语音识别工具包&#xff1a;零基础快速上手指南 【免费下载链接】vosk-api vosk-api: Vosk是一个开源的离线语音识别工具包&#xff0c;支持20多种语言和方言的语音识别&#xff0c;适用于各种编程语言&#xff0c;可以用于创建字幕、转录讲座和访谈等。 项目地址: https…

作者头像 李华
网站建设 2026/4/18 11:00:15

智能识别之疲劳驾驶行为检测困倦检测数据集 驾驶安全监测 工业作业疲劳预警(yolo11+LSTM+数据集+模型界面)第10368期

困倦检测数据集 README类别 9 类&#xff1a; 眼睛闭合、 头部左侧眼睛闭合、 头部右侧眼睛闭合、 专注状态、 头部向下、 头部向上、 看向左侧、 看向右侧、 打哈欠数据集核心信息表项目详情类别数量及名称9 类&#xff1a;眼睛闭合、头部左侧眼睛闭合、头部右侧眼睛闭合、专注…

作者头像 李华
网站建设 2026/4/18 0:43:40

如何用LaTeX模板轻松搞定学位论文:XMU-thesis终极使用指南

如何用LaTeX模板轻松搞定学位论文&#xff1a;XMU-thesis终极使用指南 【免费下载链接】XMU-thesis A LaTeX template 项目地址: https://gitcode.com/gh_mirrors/xm/XMU-thesis 还在为论文格式调整而烦恼吗&#xff1f;厦门大学专属的XMU-thesis LaTeX模板正是你需要的…

作者头像 李华
网站建设 2026/4/18 8:50:52

1990-2023年地级市数字产业集聚水平

数据简介 数字产业集聚水平是指数字产业在一定地理空间范围内&#xff0c;相关企业、机构、要素等在数量、规模、质量、关联度以及协同创新能力等方面所达到的集中程度和协同发展状态&#xff0c;它反映了数字产业在特定区域内的集聚效应和产业生态的成熟度。 数字产业所包含…

作者头像 李华