Linux 线程同步——条件变量

news2024/12/23 23:15:02

一、条件变量的概念

如果说互斥锁是用于同步线程对共享数据的访问的话,那么条件变量则是用于在线程之间同步共享数据的值。条件变量提供了一种线程间的通知机制:当某个共享数据达到某个值的时候,唤醒等待这个共享数据的线程。如下图所示:

在这里插入图片描述

二、条件变量相关函数

1.pthread_cond_init()初始化条件变量

在这里插入图片描述

参数解释:

第一个参数cond:条件变量
第二个参数attr:条件变量属性,通常传NULL,表示使用默认属性

2.pthread_cond_wait()等待条件变量满足

在这里插入图片描述

功能:阻塞等待一个条件变量(等待唤醒)并解除相应的锁资源

参数解释:
第一个参数cond:条件变量
第二个参数mutex:是用于保护条件变量的互斥锁,以确保pthread_cond_wait操作的原子性。在调用pthread_cond_wait之前必须确保互斥锁mutex已经加锁,否则将会出现多个线程同时要进入等待队列的情况导致不可预期的结果。pthread_cond_wait在执行时,首先把调用线程放入条件变量的等待队列中,然后将互斥锁解锁。从pthread_cond_wait开始执行到其调用线程被放入条件变量的等待队列之间的这段时间内,pthread_cond_signal和pthread_cond_broadcast等函数不会修改条件变量的值。也就是说,当线程在进出条件变量的等待队列的时候是不会去唤醒等待队列中的其他线程的。当pthread_cond_wait函数成功返回时,互斥锁mutex将再次被锁上,这是pthread_cond_wait函数内部做的事情,就是为了防止在唤醒某个线程的时候和其他线程进出等待队列发生冲突。如果有一个线程正在进入等待队列,这时想要唤醒某个线程时就需要加锁,就会加锁失败,要等正在进入等待队列的线程彻底进去之后解锁,然后才能加锁去唤醒想要唤醒的线程,然后再加锁,然后出等待队列的之后在进行解锁。

注意:
线程被唤醒,pthread_cond_wait函数返回时,解除阻塞并重新申请获取互斥锁。

3.pthread_cond_broadcast()唤醒全部在等待条件变量的线程

在这里插入图片描述

参数解释:

参数cond:条件变量

4.pthread_cond_signal()唤醒一个在等待条件变量的线程(随机唤醒一个)

在这里插入图片描述

参数解释:

参数cond:条件变量

5.pthread_cond_destroy()销毁条件变量

在这里插入图片描述

参数解释:

参数cond:条件变量

三、条件变量的使用

【例】有两个线程A和B在等待队列中,给一个数组buff,当从键盘上向buff中写入数据之后,就随机唤醒一个线程去读取buff中的内容并输出,当从键盘上向buff中写入"end"的时候,唤醒所有正在等待的线程,让所有线程退出。

上例中,条件变量就是用户从键盘输入的数据,线程A和线程B根据条件变量的情况被唤醒。

代码如下 :

#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<pthread.h>
#include<string.h>
#include<semaphore.h>

pthread_cond_t cond;
pthread_mutex_t mutex;

char buff[128]={0};

void* fun_a(void* arg)
{
    while(1)
    {
        //在线程A进入等待队列之前加锁,如果加锁成功,线程A进入等待队列,这时别的线程不可以进入等待队列
        pthread_mutex_lock(&mutex);

        //线程A进入等待队列中,线程B被阻塞,解锁,线程A被唤醒,加锁
        pthread_cond_wait(&cond,&mutex);

        //在线程A从等待队列出来之后,解锁,这时别的线程就可以进入等待队列
        pthread_mutex_unlock(&mutex);
        if(strncmp(buff,"end",3)==0)        
        {
            break;
        }
        else
        {
            printf("线程A输出:%s",buff);
        }

    }
    printf("线程A结束\n");
}

void* fun_b(void* arg)
{
    while(1)
    {
        //在线程B进入等待队列之前加锁,如果加锁成功,线程B进入等待队列,这时别的线程不可以进入等待队列
        pthread_mutex_lock(&mutex);

        //线程B进入等待队列中,线程B被阻塞,解锁,线程B被唤醒,加锁
        pthread_cond_wait(&cond,&mutex);

        //在线程B从等待队列出来之后,解锁,这时别的线程就可以进入等待队列
        pthread_mutex_unlock(&mutex);

        if(strncmp(buff,"end",3)==0)
        {
            break;
        }
        else
        {
            printf("线程B输出:%s",buff);
        }
    }
    printf("线程B结束\n");
}

int main()
{
    pthread_mutex_init(&mutex,NULL);
    pthread_cond_init(&cond,NULL);

    pthread_t id1,id2;
    pthread_create(&id1,NULL,fun_a,NULL);
    pthread_create(&id2,NULL,fun_b,NULL);

    while(1)
    {
        
        fgets(buff,128,stdin);

        if(strncmp(buff,"end",3)==0)
        {
            //唤醒所有
            pthread_cond_broadcast(&cond);
            break;
        }
        else
        {
            //随机唤醒一个
            pthread_cond_signal(&cond);
        }
    }

    pthread_join(id1,NULL);
    pthread_join(id2,NULL);

    pthread_mutex_destroy(&mutex);
    pthread_cond_destroy(&cond);

    exit(0);
}

运行结果:

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/912092.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Java【手撕双指针】LeetCode 202. “快乐数“, 图文详解思路分析 + 代码

文章目录 前言一、快乐数1, 题目2, 思路分析3, 代码展示 前言 各位读者好, 我是小陈, 这是我的个人主页, 希望我的专栏能够帮助到你: &#x1f4d5; JavaSE基础: 基础语法, 类和对象, 封装继承多态, 接口, 综合小练习图书管理系统等 &#x1f4d7; Java数据结构: 顺序表, 链表,…

Ubuntu系列弹性云服务器如何安装图形化界面?

​ 参考链接&#xff1a;Ubuntu系列弹性云服务器如何安装图形化界面&#xff1f; 操作场景 为了提供纯净的弹性云服务器系统给客户&#xff0c;Ubuntu系列弹性云服务器默认未安装图形化界面&#xff0c;如果您需要使用图形化界面&#xff0c;请参见本节内容进行安装。 对于GPU加…

Python支持下最新Noah-MP陆面模式站点与区域数据的处理、单站和区域的模拟、模拟结果的输出和后续分析及可视化

目录 Noah-MP 5.0模型介绍&模型所需环境的搭建 Python教程 Noah-MP 5.0模型站点模拟 Noah-MP 5.0模型区域模拟 更多应用 熟悉陆表过程的主要研究内容以及陆面模型在生态水文研究中的地位和作用&#xff1b;深入理解Noah-MP 5.0模型的原理&#xff0c;掌握Noah-MP模型&…

Video-LLaMA

文章目录 链接主要贡献模型一些思考啥是Q-former为什么position embedding可以辅助学到temporal的信息 代码视觉处理 一些惊喜 链接 https://github.com/DAMO-NLP-SG/Video-LLaMA 主要贡献 能够捕捉到一小小短时间&#xff08;temporal&#xff09;里视觉的变化 - 使用了Q-f…

“卷王”新茶饮们:从风口,卷到了十字路口

【潮汐商业评论/原创】 “楼下奈雪开业了&#xff0c;扫码9块9就可以喝到杨枝甘露&#xff0c;这也太便宜了&#xff0c;”Chloe向同事说道。 “上次跟Fendi联名的喜茶&#xff0c;两杯也只要38元。” “喜茶奈雪开始向二线价格靠拢&#xff1f;怎么都那么便宜了&#xff1f…

【一对一学习小组】2023年有三AI-CV初阶-基础算法组发布,如何夯实深度学习图像识别算法理论基础与实践...

2023年有三AI-CV初阶-基础算法组正式发布&#xff01;有三AI已经推出了CV初-中-高级培养计划&#xff08;原名有三AI-CV季划&#xff09;&#xff0c;这是我们的终身计算机视觉学习小组。 该培养计划具有以下特点&#xff1a; 【系统性】配套有非常完备的理论与实践 【永久性】…

jacaScript的详解与使用2

javaScript详解与使用2 Window.open()和location对象在HTML中我们一般使用的是a标签进行页面的跳转 而在js中也有自己的跳转页面的方式 window.open() 里面可以传递参数 在跳转的页面使用location对象进行接收 面象对象什么是面向对象1.面向对象是一种编程思想 简称为oop&#…

Qt快速学习(二)--QMainWindow,对话框,布局管理器,常用控件

目录 1 QMainWindow 1.1 菜单栏 1.2 工具栏 1.3 状态栏 1.4 铆接部件 1.5 核心部件&#xff08;中心部件&#xff09; 1.6 资源文件 2 对话框QDialog 2.1 基本概念 2.2 标准对话框 2.3 自定义消息框 2.4 消息对话框 2.5 标准文件对话框 3 布局管理器 3.1 系统…

华为OD机试 - 数字颠倒(Java 2023 B卷 100分)

目录 专栏导读一、题目描述二、输入描述三、输出描述四、解题思路五、Java算法源码六、Java算法源码投机取巧七、效果展示 华为OD机试 2023B卷题库疯狂收录中&#xff0c;刷题点这里 专栏导读 本专栏收录于《华为OD机试&#xff08;JAVA&#xff09;真题&#xff08;A卷B卷&am…

回归预测 | MATLAB实现PSO-RF粒子群优化算法优化随机森林算法多输入单输出回归预测(多指标,多图)

回归预测 | MATLAB实现PSO-RF粒子群优化算法优化随机森林算法多输入单输出回归预测&#xff08;多指标&#xff0c;多图&#xff09; 目录 回归预测 | MATLAB实现PSO-RF粒子群优化算法优化随机森林算法多输入单输出回归预测&#xff08;多指标&#xff0c;多图&#xff09;效果…

链表的顶级理解

目录 1.链表的概念及结构 2.链表的分类 单向或者双向 带头或者不带头 循环或者非循环 3.无头单向非循环链表的实现 3.1创建单链表 3.2遍历链表 3.3得到单链表的长度 3.4查找是否包含关键字 3.5头插法 3.6尾插法 3.7任意位置插入 3.8删除第一次出现关键字为key的节点 …

ROS2与ROS1通信

文章目录 准备工作通信包安装启动ros1_bridge在ROS1中启动相机节点在ROS2中查看ROS1话题 准备工作 本机系统20.04 ROS2-foxyROS1-noetic 两个版本的ROS 均需要按照官网教程进行安装&#xff0c;安装完成以后&#xff0c;source环境变量都不放到~/.bashrc文件里面 通信包安装…

MES管理系统和MOM系统哪个更适合中小企业

中小型制造企业需要在选择制造管理系统前进行充分的需求分析和系统评估&#xff0c;结合企业的战略目标和资源状况来做出决策。MES和MOM系统是两种常见的制造管理系统&#xff0c;它们都能够帮助企业提高生产效率、降低生产成本&#xff0c;实现持续发展。然而&#xff0c;MES管…

模糊测试面面观 | 模糊测试对软件质量和性能的影响

随着软件行业的几十年发展和数字化转型的加快&#xff0c;我国已经度过了软件行业的野蛮发展时代。用户对软件的质量和性能要求越来越高&#xff0c;已经成为企业成功与否的至关重要条件。然而&#xff0c;随着软件规模的扩大和黑客攻击方式的多样化&#xff0c;保障软件的安全…

【kubernetes】Helm

什么是 Helm 每个成功的软件平台都有一个优秀的打包系统&#xff0c;比如Debian、Ubuntu 的 apt&#xff0c;RedHat、CentOS 的 yum。Helm 则是 Kubernetes上 的包管理器&#xff0c;方便我们更好的管理应用。 在没使用 helm 之前&#xff0c;向 kubernetes 部署应用&#xf…

昌硕科技、世硕电子同步上线法大大电子合同

近日&#xff0c;世界500强企业和硕联合旗下上海昌硕科技有限公司&#xff08;以下简称“昌硕科技”&#xff09;、世硕电子&#xff08;昆山&#xff09;有限公司&#xff08;以下简称“世硕电子”&#xff09;的电子签项目正式上线。上线仪式在上海浦东和硕集团科研大楼举行&…

VSCode如何为远程安装预设(固定)扩展

背景 在使用VSCode进行远程开发时&#xff08;python开发之远程开发工具选择_CodingInCV的博客-CSDN博客&#xff09;&#xff0c;特别是远程的机器经常变化时&#xff08;如机器来源于动态分配&#xff09;&#xff0c;每次连接新的远程时&#xff0c;都不得不手动安装一些开…

操作系统-笔记-第四章-文件管理

目录 四、第四章——文件管理 1、文件管理——基础概念 &#xff08;1&#xff09;文件结构 &#xff08;2&#xff09;操作系统提供的接口 &#xff08;3&#xff09;总结 2、文件的逻辑结构 &#xff08;1&#xff09;有结构文件&#xff08;类似SQL表文件&#xff09…

数据分析案例丨商品零售购物篮分析(下)

数据分析案例丨商品零售购物篮分析&#xff08;上&#xff09; 03 数据预处理 通过对数据探索分析&#xff0c;发现数据数据完整&#xff0c;并不存在缺失值。建模之前需要转变数据的格式&#xff0c;才能使用apriori函数进行关联分析。对数据进行转换&#xff0c;如代码清单…

TIA博途中的数据类型基本介绍

TIA博途中的数据类型基本介绍 基本数据类型 Bool 布尔 FALSE 或TRUE 举例: I0.0 Q0.2 M100.0 DB0.DBX2.5 Byte 字节 二进制:2#0000 0000 到2#1111 1111 无符号整数:0到255 有符号整数:-128到127 十六进制:16#00到16#FF 举例: IB2 MB100 DB1.DBB2 Word 字 二进制:2#0000 …