【Linux多线程编程-自学记录】10.条件变量

2023-05-16

Linux多线程编程学习代码(代码已上传gitee,还请各位兄弟点个Star哦!)

https://gitee.com/chenshao777/linux_thread.git


笔记:
1.条件变量引入
需要一种机制,当互斥量被锁柱后,发现当前线程还是无法完成自己的操作
那么它应该自己释放互斥量,让其他线程得以工作

方法1:采用轮询方式
方法2:让系统查询条件,使用系统条件变量 pthread_cond_t cond

2.条件变量初始化和销毁
条件变量使用之前需要初始化
1、pthread_cond_t cond = PTHREAD_COND_INITIALIZER;
2、int pthread_cond_init(pthread_cond_t *restrict cond,
                      const pthread_condattr_t *restrict attr)
第一个参数是条件变量
第二个参数默认属性为空NULL
条件变量使用完成之后需要销毁
int pthread_cond_destroy(pthread_cond_t *cond);

3.条件变量的使用
条件变量使用雷要配合互斥量
int pthread_cond_wait(pthread_cond_t *restrict cond.
pthread_mutex_t *restrict mutex);
1、使用pthread_cond_wait等待条件变为真。传递给pthread_cond_wait的互斥量对条件进行保护,调用者把锁住的互斥量传递给函数。
2、这个函数将线程放到等待条件的线程列表上,然后对互斥量进行解锁,这是个原子操作。当条件满足时这个函数返回,返回以后维续对互斥量加锁。
int pthread_cond_timedwait(pthread_cond_t *restrict cond,
pthread_mutex_t *restrict mutex,
const struct timespec *restrict abstime);
3、这个函数与pthread_cond_wait类似,只是多一个timeout,如果到了指定的时间条件还不满足,那么就返回。
时间用下面的结构体表示
struct timespec{
time_t tv_sec;
long tv_nsec;
}:
注意。这个时间是绝对时间。例如你要等待3分钟,就要把当前时间加上3分钟然后转换到timespec·而不是直接将3分钟转换到timespec

当条件满足的时候,需要唤醒等侍条件的线程
int pthread_cond_broadcast(pthread_cond_t *cond);
Iint pthread_cond_signal(pthread_cond_t *cond);
1、pthread_cond_broadcast 唤醒等待条件的所有线程(广播)
2、pthread_cond_signal 至少唤醒等待条件的某一个线程
注意,一定要在条件改变以后在唤醒线程


spu.h文件

#ifndef _SPU_H_
#define _SPU_H_

#include<stdio.h>
#include<pthread.h>
#include<stdlib.h>
#include<string.h>
#include<unistd.h>
#include<sys/types.h>
#include<signal.h>
#include<errno.h>

#endif

10.thread_cond.c文件
1.创建两个线程,都对 money 全局变量进行操作
2.线程1每次对 money 加10
3.线程2每次对 money 加0.01
4.如果出现互斥的情况,线程1会输出小数

/*
  1.创建一个生产者,两个消费者
  2.生产者0.5秒生产一个产品,并且发送条件变量广播唤醒等待的线程
  3.消费者1秒消费一个产品
  4.条件变量要配合互斥锁
*/

#include "spu.h"
#include <time.h>

/*产品结构体*/
typedef struct product{
    int num;
    struct product *next;  //指向下一个产品
}product_t;

/*定义第一个产品:链表首节点*/
product_t *head = NULL;

/*初始化互斥锁*/
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;  //使用宏定义初始化互斥锁
/*初始化条件变量*/
pthread_cond_t cond = PTHREAD_COND_INITIALIZER;     //使用宏定义初始化条件变量

/*
  生产者线程
*/
void *thread_product(void *arg)
{
    for(;;)
    {
        //申请一个新的节点
        product_t *p = (product_t*)malloc(sizeof(product_t));
        p->num = rand() % 100 + 1;  //生成 1-100 之间的随机数

        //加锁
        pthread_mutex_lock(&mutex);
        
        //向链表表头加节点
        p->next = head;
        head = p;
        printf("生产者:%d\n",head->num);

        //解锁
        pthread_mutex_unlock(&mutex);
        //通知所有/单个消费者
        pthread_cond_broadcast(&cond);
        
        usleep(500000);
    }
}

/*
  消费者线程1
*/
void *thread_consume01(void *arg)
{
    for(;;)
    {
        //加锁
        pthread_mutex_lock(&mutex);

        //如果没有产品则等待
        if(head->next == NULL)
          //等待被通知,如果无通知,则自解锁(通过第二个参数),进入阻塞状态,等待被系统唤醒
          pthread_cond_wait(&cond, &mutex);
        //得到通知,开始消费
        printf("消费者1:%d\n", head->num);
        head = head->next;

        //解锁
        pthread_mutex_unlock(&mutex);
        usleep(1000000);

    }
}

/*
  消费者线程2
*/
void *thread_consume02(void *arg)
{
    for(;;)
    {
        //加锁
        pthread_mutex_lock(&mutex);

        //如果没有产品则等待
        if(head->next == NULL)
          //等待被通知,如果无通知,则自解锁(通过第二个参数),进入阻塞状态,等待被系统唤醒
          pthread_cond_wait(&cond, &mutex);
        //得到通知,开始消费
        printf("消费者2:%d\n", head->num);
        head = head->next;

        //解锁
        pthread_mutex_unlock(&mutex);
        usleep(1000000);

    }
}

int main()
{
    srand((unsigned int)time(NULL));  //设置随机种子          
    pthread_t pro_pid, con_pid1, con_pid2;
    void *_return1,*_return2,*_return3;

    /*创建生产者线程*/
    pthread_create(&pro_pid, NULL, thread_product, NULL);
    /*创建消费者线程1*/
    pthread_create(&con_pid1, NULL, thread_consume01, NULL);
    /*创建消费者线程2*/
    pthread_create(&con_pid2, NULL, thread_consume02, NULL);


    /*等待线程结束*/
    pthread_join(pro_pid,_return1);
    pthread_join(con_pid1,_return2);
    pthread_join(con_pid2,_return3);

    /*销毁互斥量*/
    pthread_mutex_destroy(&mutex);
    /*销毁条件变量*/
    pthread_cond_destroy(&cond);
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

【Linux多线程编程-自学记录】10.条件变量 的相关文章

  • FreeRTOS 框架

    官网 章节目录规划 Kernel taskmemory managementqueue mutex semaphoretime managesoftware timerinterrupt process FreeRTOS plus Free
  • 飞行器设计之界限线图

    推重比与翼载荷约束分析 主要性能要求可以表示为最小起飞推重比T W和起飞翼载荷W S的函数 xff0c 每一项性能要求可以在起飞推重比T W 起飞翼载荷W S坐标中构成一条约束曲线 采用能量守恒方程 xff0c 推导出飞机性能约束的一般主管
  • FreeRTOS中使用中断的一些注意事项

    1 几个宏定义的解释 configLIBRARY LOWEST INTERRUPT PRIORITY 这个宏是可以定义的中断最低优先级 xff0c 由于STM32中断管理只用了4位来分配抢占优先级和子优先级 xff0c 并且FreeRTOS
  • 软路由cpu性能跑分

    软路由cpu性能跑分 cpu核心功耗单核多核N50304 46W14052909N50004 46W11522608N41204 46W11072477N41004 46W9952238N42004 46W8362027N34504 46W
  • k8s中pod的基本概念以及pod内资源共享的分析与实现

    目录 pod基本概念 xff1a pod的主要用法 pod资源共享实现机制 pod网络共享测试案例 xff1a 存储共享 pod存储共享测试案例 xff1a pod管理命令 常用的pod管理命令 定义pod pod基本概念 xff1a po
  • 迅雷笔试题2014校园招聘 武汉

  • C#中的readonly与const区别

    xfeff xfeff const 的概念就是一个包含不能修改的值的变量 常数表达式是在编译时可被完全计算的表达式 因此不能从一个变量中提取的值来初始化常量 如果 const int a 61 b 43 1 b是一个变量 xff0c 显然不
  • 改变无线连接、有线连接的优先级

    有线和无线连的是同一个网络 xff0c 当笔记本打开时 xff0c 总是优先使用无线连接 xff0c 如何转变优先级为有线连接呢 xff1f 1 打开网络和共享中心 2 更改适配器设置 xff0c 打开网络连接窗口 3 单击此窗口的高级菜单
  • 杂感一

    从2014年7月工作至今已有快2年了 xff0c csdn的博客从毕业后就很少上了 工作中有很多收获 技术上 也在不断积累和成长中 不管做什么事情 xff0c 要坚持下去 xff0c 方得初心 xff0c 把坚持养成习惯 xff0c 学习如
  • MFC隐藏主窗口的方法

    隐藏基于对话框的MFC应用程序窗口的方法 推荐这个方法 xff0c 非常好用 很多人可能会将窗口创建出来 然后用一个 ShowWindow SW HIDE 的方法去隐藏窗口 当然这是可以做到隐藏的功能 但是有一点不足的地方就是窗口在隐藏之前
  • JSP 通过Servlet将excel数据导入SQL

    1 gt 在网上下载jxl jar 这个JAR包用于Java操作excel 下载后 xff0c 将这个包复制到工程Webroot下的WEB INF下的lib中 xff0c 或是在工程中导入jxl jar包 2 gt 准备excel文件 如图
  • 1=5,2=15,3=215,4=2145,那么5=?

    如题 xff0c 1 61 5 xff0c 2 61 15 xff0c 3 61 215 xff0c 4 61 2145 xff0c 那么5 61 xff1f 答案 xff1a 5 61 1 哎 xff0c 这个题出的 xff0c 没反应过
  • 数值分析上机题Matlab--东南大学出版社(牛顿迭代/逐次超松弛迭代/3次样条插值/复合梯形SimpsonRomberg/四阶经典Runge-Kutta/幂法求特征向量)

    第二章上机题 Newton迭代法 function x err 61 Newton f x0 epsilon 用例 xff1a x err 61 Newton 39 x 3 3 x 39 0 7 0 005 Input f 字符串公式 39
  • 村子里有50个人,每人有一条狗,在这50条狗中有病狗(这种病不传染),于是人们要找出病狗。

    xff29 xff22 xff2d 公司向来以高素质人才作为企业持续竞争力的保证 进入 xff29 xff22 xff2d 公司是差不多每个 xff29 xff34 人的梦想 下面这条 xff29 xff22 xff2d 公司的面试题 xf
  • 删除单向链表中的某一个节点

    已知一个单向链表的表头head xff0c 写出一个删除某一个节点的算法 xff0c 要求先找到此节点 xff0c 然后删除 include lt iostream gt using namespace std typedef struct
  • 多段图的最短路径问题-----动态规划法

    对多段图 xff0c 求最短路径 xff0c 如图 xff1a 对其使用动态规划法 xff1a 阶段 xff1a 将图中的顶点划分5个阶段 xff0c k 状态 xff1a 每个阶段有几种供选择的点s 决策 xff1a 当前状态应在前一个状
  • Ceres-Solver学习笔记(6)

    溯洄从之 xff0c 道阻且长 建模最小化二乘问题 Ceres有两个组成部分 xff0c 一个是建模API xff0c 它提供了一组丰富的工具 xff0c 可以在一段时间内构造一个优化问题 xff0c 另一个是求解程序API xff0c 控
  • hualinux2.1 环境搭建:源码、二进制、yum/apt安装区别

    一 linux软件常用的安装方式 linux软件常见的安装方式一般分以下几种 xff1a 1 源码安装 xff1a 直接通过源代码安装 一般用make或cmake安装 2 二进制安装 xff1a 别人已经帮编译好了 xff0c 拿过来就可以
  • 百度试题---开发测试工程师

    一 问答题 说出常用的几种希哈函数 xff0c 其作用是什么 xff1f 描述OSI 的七层网络结构 xff0c HTTP 工作在哪一层 xff1f 描述一段C 语言代码程序能运行起来的代码要求和执行过程 二 算法设计 有一车苹果 xff0
  • ((硬件spi+dma)+模拟spi)驱动LCD5110

    span class hljs preprocessor ifndef spi dma h span span class hljs preprocessor define spi dma h span span class hljs pr

随机推荐

  • 《Python深度学习》第五章-2(Cats_vs_Dogs)读书笔记

    5 2 在小型数据集上从头开始训练一个卷积神经网络 当数据不够时 xff0c 有以下方法进行处理 xff0c 本节主要是介绍数据增强 5 2 1 深度学习与小数据问题的相关性 深度学习的一个基本特性就是能够独立地在训练数据中找到有趣的特征
  • 无人机原理图、pcb图下载地址

    原理图 pcb图下载地址 无人机pcb电路图原理图 智能家居文档类资源 CSDN文库
  • Win 10 系统下搭建 Python 编程环境,有手就行

    前言 想把一门编程语言学好 xff0c 会搭建编程环境无疑是有必要的 xff0c 纵然有线上集成的编程环境 xff0c 但那高度依赖于网络条件以及诸多情况 xff0c 这使得我们在编程的时候难以存储自己的资料 学习和使用 python 一年
  • Latex小白学习方法和实践

    1 了解简单语法 xff0c 读懂latex解决的问题 xff0c 和其核心方法论 知道latex其实不是万金油 xff0c 只是在熟悉的情况下 xff0c 让你更完美的排版 xff0c 省去可视化下不精确的问题 xff0c 其不会很快的完
  • PADS版本历史

    从加载文件的速度 xff0c 生成的文件大小 xff0c 画图的速度 xff0c 渲染的速度等多方面来说 xff0c 个人认为 PDAS 算是非常不错的一款软件 xff0c 值得学习和使用 大概把其光辉历史罗列一下 xff0c 作为一个回忆
  • 简述Z-Stack的基本工作原理与流程(OSAL操作系统)

    首先上图 xff0c 跟着图中的函数顺序来感受Z Stack的工作流程 xff1a Z Stack协议栈总的来说做了两件事 xff0c 系统的初始化和启动OSAL操作系统 系统初始化 xff1a 从main函数看 xff0c 首先是调用了o
  • 使用MaixPy IDE开发K210

    使用MaixPy IDE快速开发K210 距离我第一次使用MaixPy将近40天了 xff0c 大概花了26天 xff0c 完成了我的毕业设计并且进行了优化 后面我会花时间去和大家分享我的毕设 xff0c 也希望能得到各位码友的意见和建议
  • K210实现人脸识别(附代码解读)

    基于K210的人脸识别门禁 xff08 一 xff09 进入官网 xff08 首次登陆需要注册 xff09 获取人脸识别源码 https wiki sipeed com soft maixpy zh course ai image face
  • K210人脸识别+人脸信息存储

    在我的上一篇博客中已经介绍了如何使用K210实现基本的人脸识别功能 https blog csdn net HuangChen666 article details 113995079 spm 61 1001 2014 3001 5501
  • 旅行商问题--蚁群优化算法求解(matlab实现)

    今天给大家分享一下matlab实现蚁群优化算法 xff0c 解决旅行商问题 在上一篇博客中对蚁群优化算法做了较为详细的介绍 xff0c 有需要的小伙伴可以看一下 https blog csdn net HuangChen666 articl
  • 粒子群优化算法及MATLAB实现

    上一篇博客是关于蚁群优化算法的 xff0c 有兴趣的可以看下 https blog csdn net HuangChen666 article details 115913181 1 粒子群优化算法概述 2 粒子群优化算法求解 2 1 连续
  • A星(A*、A Star)路径规划算法详解(附MATLAB代码)

    首先看看运行效果 xff0c 分别有三种模式 xff0c 代码运行前需要通过鼠标点击设置起点和终点 第一种模式直接输出最短路径 第二种模式输出最短路径的生成过程 第三种模式输出最短路径的生成过程和详细探索的过程 代码获取 gitee链接 x
  • Ubuntu20.04+MAVROS+PX4+Gazebo保姆级安装教程

    Ubuntu20 04 43 MAVROS 43 PX4 43 Gazebo 安装PX4步骤安装MAVROS安装QGCPX4仿真 安装PX4步骤 从github上clone源码 span class token function git s
  • PX4+Offboard模式+代码控制无人机起飞(Gazebo)

    参考PX4自动驾驶用户指南 https docs px4 io main zh ros mavros offboard cpp html 我的另一篇博客写了 键盘控制PX4无人机飞行 PX4无人机 键盘控制飞行代码 可以先借鉴本篇博客 xf
  • 基于ESP32的小型四轴无人机

    粗糙版试飞成功 xff01 陀螺仪部分直接飞线飞了一个模块 xff0c 懒得焊了 不是很水平 xff0c 稳定性不是很好 因为滤波算法中加入的元素太少了 xff0c 目前也就MPU6050的输出数据加入了计算 xff0c 所以很多自稳定性飞
  • PX4无人机 - 键盘控制飞行代码

    PX4无人机 键盘控制飞行代码 仿真效果 实机效果 由于图片限制5M以内 xff0c 只能上传一小段了 xff0c 整段视频请点击链接 Pixhawk 6c 无人机 键盘控制无人机 Offboard模式 核心 xff1a 发布 mavros
  • 【FreeRTOS学习 - 消息队列学习】

    跟着韦东山老师FreeRTOS教学资料的学习记录 FreeRTOS全部项目代码链接 xff08 更新中 xff09 https gitee com chenshao777 free rtos study 本文章一共分为一下几个部分 1 创建
  • 【Linux多线程编程-自学记录】08.Linux多线程互斥量

    Linux多线程编程学习代码 xff08 代码已上传gitee xff0c 还请各位兄弟点个Star哦 xff01 xff09 https gitee com chenshao777 linux thread git 笔记 xff1a 1
  • 【Linux多线程编程-自学记录】09.Linux多线程之读写锁

    Linux多线程编程学习代码 xff08 代码已上传gitee xff0c 还请各位兄弟点个Star哦 xff01 xff09 https gitee com chenshao777 linux thread git 笔记 xff1a 1
  • 【Linux多线程编程-自学记录】10.条件变量

    Linux多线程编程学习代码 xff08 代码已上传gitee xff0c 还请各位兄弟点个Star哦 xff01 xff09 https gitee com chenshao777 linux thread git 笔记 xff1a 1