线程条件变量 生产者消费者模型 Linux环境 C语言实现

只能用来解决同步问题,且不能独立使用,必须配合互斥锁一起用


头文件:#include <pthread.h>
类型:pthread_cond_t
PTHREAD_COND_INITIALIZER 初始化
初始化:int pthread_cond_init(pthread_cond_t * cond, NULL);
清理:int pthread_cond_destroy(pthread_cond_t * cond);
P操作: 
     int pthread_cond_wait(pthread_cond_t * cond, pthread_mutex_t *mutex);//mutex必须是pthread_mutex_lock返回后的
V操作: int pthread_cond_signal(pthread_cond_t * cond);//只是出队任务等待队列中的第一个任务,让该任务正在阻塞的P操作返回
V操作: int pthread_cond_broadcast(pthread_cond_t * cond);//出队任务等待队列中的所有任务,让所有正阻塞的任务的P操作返回

功能:见函数名
返回值:成功0,失败错误码
mutex为已经处于锁状态的互斥锁,因此条件变量必须与一个互斥量配合使用


代码模板:

代码模板:
pthread_cond_t cond;
pthread_mutex_t lock;

程序开始时:
pthread_mutex_init(&lock,NULL);
pthread_cond_init(&cond,NULL);

程序结束前:
pthread_mutex_destroy(&lock);
pthread_cond_destroy(&cond);

A线程为先做线程
pthread_mutex_lock(&lock);
....
pthread_mutex_unlock(&lock);
pthread_cond_signal(&cond);


B线程为后做线程
pthread_mutex_lock(&lock);
if(条件表达式为真)
{
	pthread_cond_wait(&cond,&lock);
}
.....
pthread_mutex_unlock(&lock);

生产者消费者模型(生产者生产出来东西后消费者才能执行)

问题:设计程序,一个线程实现入队操作,另一个实现出队操作, 如果队列中没有数据,出队线程不参与资源的竞争.(条件变量)
代码:
#include <stdio.h>
#include <pthread.h>
#include <stdlib.h>
#include <assert.h>
#include <unistd.h>

#if  0
条件变量在生产者消费者模型中使用步骤:
1、定义条件变量和互斥锁,并初始化

消费者线程:
1、加锁
 int pthread_mutex_lock(pthread_mutex_t *mutex);

2、判断公共资源中是否有数据
while(公共资源中没有数据成立)
{
    //造成线程的阻塞,在阻塞之前进行解锁
    //被唤醒后,申请加锁
    int pthread_cond_wait(pthread_cond_t *cond, pthread_mutex_t *mutex);

}

3、如果公共资源中有数据, 消费数据


4、解锁
int pthread_mutex_unlock(pthread_mutex_t *mutex);


生产者线程:
1、加锁
 int pthread_mutex_lock(pthread_mutex_t *mutex);

2、生产数据, 并放到公共资源中

3、解锁
int pthread_mutex_unlock(pthread_mutex_t *mutex);

4、发送信号给条件变量, 唤醒所有阻塞在条件变量上的线程
  int pthread_cond_signal(pthread_cond_t *cond);

#endif

struct  node{
    int data;
    struct node *next;
};

pthread_cond_t cond = PTHREAD_COND_INITIALIZER; // 初始化cond条件变量
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; // 初始化mutex锁

struct node *head = NULL;

//生产者线程
void* product(void* argv){
    struct node *pnew = NULL;
    // sleep(10);
    while(1){
        pnew = malloc(sizeof(struct node));
        assert(pnew != NULL);

        pnew->data = rand();
        pnew->next = NULL;

        printf("========product: %d\n", pnew->data);

        pthread_mutex_lock(&mutex); // 上锁

        pnew->next = head;
        head = pnew;

        pthread_mutex_unlock(&mutex); // 解锁

        pthread_cond_signal(&cond); // 发出信号

        sleep(1);
    }

    return NULL;
}

//消费者线程
void*  consumer(void* argv){
    struct node *pdel = NULL;
    while(1){
        pthread_mutex_lock(&mutex); // 上锁

        while(NULL == head){ // 判断条件是否满足
            printf("wait..\n");
            pthread_cond_wait(&cond, &mutex); // 解锁等待,条件满足后再上锁
            printf("wait  over...\n");
        }
        printf("------->consumer: %d\n", head->data);
        pdel = head;
        head = head->next;
        free(pdel);

        pthread_mutex_unlock(&mutex); // 解锁

        sleep(1);
    }
    return NULL;
}


int main(){
    pthread_t  pth1, pth2;

    if(0 != pthread_create(&pth1, NULL, product, NULL)){
       perror("pthread_create");
       return -1;
    }

    if(0 != pthread_create(&pth2, NULL, consumer, NULL)){
       perror("pthread_create");
       return -1;
    }

    pthread_join(pth1, NULL); // 回收线程
    pthread_join(pth2, NULL);

    pthread_mutex_destroy(&mutex); // 销毁锁
    pthread_cond_destroy(&cond); // 销毁条件变量

    return 0;
}

输出:

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Springboot美食分享平台

私信我获取源码和万字论文&#xff0c;制作不易&#xff0c;感谢点赞支持。 Springboot美食分享平台 一、 绪论 1.1 研究意义 当今社会作为一个飞速的发展社会&#xff0c;网络已经完全渗入人们的生活&#xff0c; 网络信息已成为传播的第一大媒介&#xff0c; 可以毫不夸张…

爬虫(JAVA笔记第四十期)

p.s.这是萌新自己自学总结的笔记&#xff0c;如果想学习得更透彻的话还是请去看大佬的讲解 目录 正则表达式爬虫 正则表达式 正则表达式可以用来校验字符串是否满足一定的规则&#xff0c;并用来校验数据格式的合法性&#xff1b;也可以在一段文本中查找满足要求的内容 单字符…

【实战教程】小目标检测利器:使用YOLOv8和SAHI进行视频检测,检测效果真心不错

《------往期经典推荐------》 一、AI应用软件开发实战专栏【链接】 项目名称项目名称1.【人脸识别与管理系统开发】2.【车牌识别与自动收费管理系统开发】3.【手势识别系统开发】4.【人脸面部活体检测系统开发】5.【图片风格快速迁移软件开发】6.【人脸表表情识别系统】7.【…

Hbase整合Mapreduce案例1 hdfs数据上传至hbase中——wordcount

目录 整合结构准备java API 编写pom.xmlMain.javaMap.javaReduce 运行 整合结构 准备 上传hdfs data.txt数据 data.txt I am wunaiieq QAQ 123456 Who I am In todays interconnected world the role of technology cannot be overstated It has revolutionized the way we …

【机器学习】—Transformers的扩展应用:从NLP到多领域突破

好久不见&#xff01;喜欢就关注吧~ 云边有个稻草人-CSDN博客 目录 引言 一、Transformer架构解析 &#xff08;一&#xff09;、核心组件 &#xff08;二&#xff09;、架构图 二、领域扩展&#xff1a;从NLP到更多场景 1. 自然语言处理&#xff08;NLP&#xff09; 2…

AMEYA360 | 杭晶电子:晶振在AR/VR中的应用

晶振在AR/VR设备中扮演重要角色&#xff0c;为其核心电子系统提供稳定的时钟信号&#xff0c;确保设备的高性能运行。 以下是晶振在AR/VR应用中的具体作用&#xff1a; 01、图像处理与同步 1、晶振为图形处理单元(GPU)和显示芯片提供精准的时钟信号&#xff0c;支持高速图像渲染…

肝硬化腹水的症状表现

‌肝硬化腹水的症状表现多样‌&#xff1a; ‌全身症状‌ 疲倦乏力&#xff0c;体力明显下降。 皮肤干枯粗糙&#xff0c;面色灰暗黝黑&#xff0c;有时可见黄疸。 双下肢浮肿&#xff0c;甚至出现蜘蛛痣、肝掌等体征‌ ‌消化道症状‌ 食欲减退&#xff0c;常伴有恶心、呕…

困扰解决:mfc140u.dll丢失的解决方法,多种有效解决方法全解析

当电脑提示“mfc140u.dll丢失”时&#xff0c;这可能会导致某些程序无法正常运行&#xff0c;给用户带来不便。不过&#xff0c;有多种方法可以尝试解决这个问题。这篇文章将以“mfc140u.dll丢失的解决方法”为主题&#xff0c;教大家有效解决mfc140u.dll丢失。 判断是否是“mf…

汽车IVI中控开发入门及进阶(三十六):QML调用蓝牙sdk的架构

Qt/QML本身在做GUI界面工程时,除了各种界面上的按钮、图片、工具条等元素之外,最方便的就是可以通过C++实现界面各种复杂逻辑,而实现上不可避免就需要一些外部库的支持,不管是静态库.a还是动态库.so,比如蓝牙模块。 而QML/C++启动一个蓝牙协议栈SDK作为一个进程,然后启动…

【SARL】单智能体强化学习(Single-Agent Reinforcement Learning)《纲要》

&#x1f4e2;本篇文章是博主强化学习&#xff08;RL&#xff09;领域学习时&#xff0c;用于个人学习、研究或者欣赏使用&#xff0c;并基于博主对相关等领域的一些理解而记录的学习摘录和笔记&#xff0c;若有不当和侵权之处&#xff0c;指出后将会立即改正&#xff0c;还望谅…

ES常见问题汇总

ES常见问题汇总 1.Es的作用&#xff08;elasticsearch&#xff09; 作用&#xff1a; elasticsearch是一款非常强大的开源搜索引擎&#xff0c;具备非常多强大功能&#xff0c;可以帮助我们从海量数据中快速找到需要的内容 ELK技术栈 elasticsearch结合kibana、Logstash&…

C# 动态类型 Dynamic

文章目录 前言1. 什么是 Dynamic&#xff1f;2. 声明 Dynamic 变量3. Dynamic 的运行时类型检查4. 动态类型与反射的对比5. 使用 Dynamic 进行动态方法调用6. Dynamic 与 原生类型的兼容性7. 动态与 LINQ 的结合8. 结合 DLR 特性9. 动态类型的性能考虑10. 何时使用 Dynamic&…

【08】MySQL复杂查询:子查询语句详解与示例

文章目录 一、子查询的基本概念子查询的基本结构子查询的类型 二、标量子查询示例 1&#xff1a;标量子查询示例 2&#xff1a;标量子查询与IN组合 三、多行子查询示例 1&#xff1a;多行子查询与IN示例 2&#xff1a;多行子查询与ANY 四、多列子查询示例 1&#xff1a;多列子查…

ApiPost调试问题

在使用ApiPost调试接口时&#xff0c;发现传参老是传不过去&#xff0c;最后发现json格式中开头需要小写(哪怕后端名称是大写)

微信 创建小程序码-有数量限制

获取小程序码&#xff1a;小程序码为圆图&#xff0c;有数量限制。 目录 文档 接口地址 功能描述 注意事项 请求参数 对接 获取小程序码 调用获取 小程序码示例 总结 文档 接口地址 https://api.weixin.qq.com/wxa/getwxacode?access_tokenaccess_token 功能描述 …

解决python 使用pip 安装模块时遇到的错误SSL: CERTIFICATE_VERIFY_FAILED

最近有一个使用python 2.7.* 使用requests模块的需求,在安装的过程中遇到了一个问题&#xff0c;在这里分享给大家&#xff01; 安装requests命令如下 pip install -i https://pypi.tuna.tsinghua.edu.cn/simple requests 遗憾的是&#xff0c;报错了 Collecting requests …

详解Java数据库编程之JDBC

目录 首先创建一个Java项目 在Maven中央仓库下载mysql connector的jar包 针对MySQL版本5 针对MySQL版本8 下载之后&#xff0c;在IDEA中创建的项目中建立一个lib目录&#xff0c;然后把刚刚下载好的jar包拷贝进去&#xff0c;然后右键刚刚添加的jar包&#xff0c;点击‘添…

Python毕业设计选题:基于大数据的淘宝电子产品数据分析的设计与实现-django+spark+spider

开发语言&#xff1a;Python框架&#xff1a;djangoPython版本&#xff1a;python3.7.7数据库&#xff1a;mysql 5.7数据库工具&#xff1a;Navicat11开发软件&#xff1a;PyCharm 系统展示 管理员登录 管理员功能界面 电子产品管理 系统管理 数据可视化分析看板展示 摘要 本…

Transformers在计算机视觉领域中的应用【第3篇:Swin Transformer——多层次的Vision Transformer】

目录 1 介绍2 摘要3 模型架构4 窗口自注意力5 移动窗口自注意力5.1 巧妙的掩码方式5.2 相对位置编码 6 总结 论文&#xff1a;Swin Transformer: Hierarchical Vision Transformer using Shifted Windows 代码&#xff1a;https://github.com/microsoft/Swin-Transformer Huggi…

江南大学《2024年807自动控制原理真题》 (完整版)

本文内容&#xff0c;全部选自自动化考研联盟的&#xff1a;《江南大学807自控考研资料》的真题篇。后续会持续更新更多学校&#xff0c;更多年份的真题&#xff0c;记得关注哦~ 目录 2024年真题 Part1&#xff1a;2024年完整版真题 2024年真题