初识Linux · 线程同步
目录
前言:
认识条件变量
认识接口
快速使用接口
生产消费模型
前言:
前文我们介绍了线程互斥,线程互斥是为了防止多个线程对临界资源访问的时候出现了对一个变量同时操作的情况,对于线程互斥来说,我们使用到了锁,而加锁的过程是原子性的,所以不用担心时间片轮转的时候发生错误,那么加锁的过程为什么是原子的我们也介绍了,因为加锁用到了cpu指令集中的swap指令,直接将内存中的值和寄存器中的值切换,只有一个汇编语句,所以是原子的。
以上是对于线程互斥部分的一个简单总结,本文,我们来介绍线程同步。
介绍线程同步我们这样介绍,从一个生活的简单例子入手,引出条件变量,然后快速的认识条件变量的接口,编写一段测试代码快速使用一下条件变量,最后的大头是生产消费模型,编写完生产消费模型,线程同步就完成了。
那么,进入主题吧!
认识条件变量
我们来假设这么一个场景:VIP自习室(只有一个人能使用),自习室的钥匙,多位同学。
其中的一位同学,从早上持有了自习室的钥匙,别的同学只能在自习室的门外等待该同学放回钥匙,终于,持有钥匙的同学出来放钥匙了,但是该同学又想继续自习,不想放钥匙,就刚把钥匙放下,就立马拿起来了,此时,其他同学刚有一点希望,就来绝望了。
这种情况是不合理的,因为其他同学无法获得钥匙,此时,我们将多个同学看作线程,钥匙是临界资源,所以就导致了饥饿问题。
所以为了合理性,对于钥匙的申请,就有了如下规定:
1->放下钥匙不能立马拿钥匙 2->第二次申请钥匙必须排队
所以,此时自习室的使用就有了一定的顺序性,我们将这种顺序性叫做线程的同步。
通过上文我们好像也没有引出来条件变量呀?
我们再来一个拿苹果的例子,A往盘子里面放苹果,B C从里面拿苹果,那么多个线程之间是独立的,它们怎么知道盘子里面是否有苹果呢?或者说,A怎么知道B C什么时候拿苹果呢?
此时需要一个铃铛吧?当A往盘子里面放了苹果,就敲一下铃铛,此时B C正在排队,B在第一个,拿了苹果就到下一个了,此时顺序性有了,条件变量是什么呢?条件变量其实就是那个铃铛!!
可是,如果没有铃铛会怎么样呢?我们首先要认识到,苹果是临界资源没错,盘子也是吧?那么没有铃铛,就没有人告诉B是否有苹果没有,B就只能自己一直探测,可是一直探测的过程中就是对临界资源的持续访问,换句话说,A就一直访问不到盘子,也就放不到苹果,这效率不就非常非常低了吗?
认识接口
所以,我们需要引出条件变量,铃铛!现在我们对于铃铛有了基本的认识,那么来认识一下它的接口吧!
因为Ubuntu系统无法查看这一类函数,所以想要查看最好使用centos系统或者其他系统查看。
那么这里和互斥锁是十分十分相似的,条件变量分为局部的和全局的,如果使用的是全局的,我们只需要使用宏即可。
如果是局部的,势必要涉及到的函数是初始化和销毁,就是pthread_cond_init 和pthread_cond_destroy函数了,它们的参数也是十分简单的,第一个是pthread_cond_t类型的条件变量指针,第二个参数是属性,我们直接设置为空即可。
当然了,pthread_cond_wait从名字上就看得出来它是要某个线程等待的,至于参数为什么还有锁的参数我们先不管,后面自然会介绍到。
有了铃铛,我们总得敲响铃铛吧?对于函数pthread_cond_signal是唤醒单个线程的,对于函数pthread_cond_broadcast是唤醒在该条件变量下等待的所有线程的,参数也是非常简单,就是条件变量的指针而已。
以上是条件变量我们要使用到的接口,还是十分的简单的吧?
快速使用接口
#include <iostream>
#include <pthread.h>
#include <string>
#include <unistd.h>const int nums = 10;
pthread_cond_t cond = PTHREAD_COND_INITIALIZER;
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;void *wait(void *args)
{std::string name = static_cast<const char*>(args);while(true){pthread_mutex_lock(&mutex);pthread_cond_wait(&cond,&mutex);usleep(10000);std::cout << "I am " << name << std::endl;pthread_mutex_unlock(&mutex);}
}
int main()
{pthread_t threads[nums];// 创建多线程for (int i = 0; i < nums; i++){char *name = new char[128];snprintf(name, 128, "thread'name - %d", i + 1);pthread_create(&threads[i], nullptr, wait, (void *)name);usleep(10000);}// 唤醒线程while (true){pthread_cond_broadcast(&cond);std::cout << "thread wake up ... " << std::endl;sleep(1);}// 等待其他线程for (int i = 0; i < nums; i++){pthread_join(threads[i], nullptr);}return 0;
}
其实使用的话是没有多难的,和之前的互斥锁一模一样,不过是在这里开始我们慢慢的埋下了伏笔而已,比如pthread_cond_wait的第二个参数是什么意思
从上面的代码来说,我们能够理解线程等待的时候,通过函数pthread_cond_wait,在该条件变量下等待,其他的更多是复习了一下之前的内容而已。
生产消费模型
对于这么一个极其简陋的图来说,就是最简单的一个生产消费模型,其中表现的是我们平常都去超市买东西,那么超市是一个生产者吗?
显然,超市不是一个生产者,真正的生产者是供应商,也就是场景,那么消费者不必多说,问题在于,超市本身扮演的地位是什么呢?
实际上,对于超市来说,它更像一种缓冲区,因为消费者不可能买那么多东西,所以一般的模式是厂家给超市,超市给消费者,超市作为缓冲区可以囤积大量的货物。
那么如果没有了超市,会有什么结果呢?
如果没有了超市,消费者直接去厂家买,一次买几包,可是厂家光是打开机器的电都可以买几百包了,如果没有了超市,消费者每次都要和厂家联系,说我们要买什么什么,这样消费者和厂家的联系变的紧密了,是一种降低效率的紧密关系,如果没有了超市,一次性生产了多个商品,那完了,厂家可以下班了,因为消费者根本就买不了那么多东西。
所以有了超市,可以让厂家和一次性生产许多,也不用担心下岗,因为有许多超市作为缓冲区放着,有了超市,可以让厂家和消费者解耦,因为有了中间媒介,既然有了中间商,那么就可以消费者一边消费生产者一边生产,效率也高,请注意,这里的效率也高和一边消费一边生产不是因为所以关系。
那么,我们转接到线程部分来看待生产消费模型,一个一个的消费者和一个一个的生产者看成是一个一个的线程,那么我们可以将生产消费模型总结一下:
一个交易场所->超市
两个角色->生产者和消费者
三个关系->生产者和生产者,消费者和消费者,生产者和消费者
前两个我们是好理解的,那么三个关系我们应该如何理解呢?
生产者和生产者之间,也就是不同的厂家之间,这是竞争关系吧?都不用想,如果没有其他的厂家,只有一个厂家,那么该厂家不知道有多爽。所以生产者和生产者之间是典型的互斥关系。
消费者和消费者之间,实际上也是互斥关系,为什么呢?平常是因为超市的东西足够,所以互斥关系不明显,如果哪天末日爆发,超市的东西有限,你看互斥关系会不会明显起来吧。
生产者和消费者之间,生产者生产好了给超市,消费者从超市里面拿数据,这就是一种顺序性,所以是一种同步关系,可是,如果超市没有东西了,消费者什么也拿不到,也就是对超市这个临界资源的访问必须暂停了,必须要等生产者生产东西给超市,此时消费者相当于就在条件变量下等待了,生产者生产了之后,登记货物的时候消费者也不能拿,必须等货物登记好了再拿,这不就是一种互斥关系吗?
那么实际上,我们面临的生产消费模型,不止有单生产单消费模型,还有多生产多消费模型。
在下篇文章中,我们就要介绍单生产单消费和多生产多消费的代码编写。
下篇文章涉及的是阻塞队列的生产消费模型和环形队列的生产消费模型。
感谢阅读!
相关文章:
初识Linux · 线程同步
目录 前言: 认识条件变量 认识接口 快速使用接口 生产消费模型 前言: 前文我们介绍了线程互斥,线程互斥是为了防止多个线程对临界资源访问的时候出现了对一个变量同时操作的情况,对于线程互斥来说,我们使用到了锁…...
游戏引擎学习第40天
仓库 : https://gitee.com/mrxiao_com/2d_game 整理了一些需要完成的任务,确保所有内容都已清理完成,因为需要为后续的数学部分打好基础。下一步将认真开始处理数学相关内容,因此在此之前,需要彻底梳理未完成的事项,清…...
概率论——假设检验
解题步骤: 1、提出假设H0和H1 2、定类型,摆公式 3、计算统计量和拒绝域 4、定论、总结 Z检验 条件: 对μ进行检验,并且总体方差已知道 例题: 1、假设H0为可以认为是570N,H1为不可以认为是570N 2、Z…...
【Pandas】pandas isnull
Pandas2.2 General Top-level missing data 方法描述isna(obj)用于检测数据中的缺失值isnull(obj)用于检测数据中的缺失值notna(obj)用于检测数据中的非缺失值notnull(obj)用于检测数据中的非缺失值 pandas.isnull() pandas.isnull() 是 Pandas 库中的一个函数,…...
Rust HashMap使用
Rust 的 HashMap 是一个功能强大的数据结构,它结合了哈希表的高效性和 Rust 编程语言的内存安全特性。通过提供常数时间复杂度的查找、插入和删除操作,以及丰富的 API,它在许多实际应用中都非常有用。 示例代码: use std::colle…...
Spring Boot如何实现防盗链
一、什么是盗链 盗链是个什么操作,看一下百度给出的解释:盗链是指服务提供商自己不提供服务的内容,通过技术手段绕过其它有利益的最终用户界面(如广告),直接在自己的网站上向最终用户提供其它服务提供商的…...
TIM输入捕获---STM
一、简介 IC输入捕获 输入捕获模式下,当通道输入引脚出现指定电平跳变时,当前CNT的值将被锁存在CCR中,可用于测量PWM波形的频率、占空比、脉冲间隔、电平持续时间等参数 每个高级定时器和通用定时器都拥有4个输入捕获通道 可配置为PWMI模…...
核密度估计——从直方图到核密度(核函数)估计_带宽选择
参考 核密度估计(KDE)原理及实现-CSDN博客 机器学习算法(二十一):核密度估计 Kernel Density Estimation(KDE)_算法_意念回复-GitCode 开源社区 引言 在统计学中,概率密度估计是一种重要的方法࿰…...
javaScript Tips
一键去掉鼠标的图标 document.body.style.cursor none; 获取一个随机颜色 const randomHex () >#${Math.floor(Math.random() * 0xffffff).toString(16).padEnd(6, 0)}; 生成随机字符串,各种随机基本都是这个原理 const randomString () > Math.rand…...
【Ubuntu】清理、压缩VirtualBox磁盘空间大小
1、说明 本人为虚拟机创建了两个硬盘:root.vdi 和 hoom.vdi,在创建虚拟机时,分别挂载在/root目录和/home目录下。 下面演示分别清理、压缩两个磁盘的空间。 2、清理空间 1)清理 root.vid sudo dd if=/dev/zero of=/EMPTY bs=1M;sudo rm -f /EMPTY输出信息中会提示,如…...
若依 ruoyi VUE el-select 直接获取 选择option 的 label和value
1、最新在研究若依这个项目,我使用的是前后端分离的方案,RuoYi-Vue-fast(后端) RuoYi-Vue-->ruoyi-ui(前端)。RuoYi-Vue-fast是单应用版本没有区分那么多的modules 自己开发起来很方便,这个项目运行起来很方便,但是需要自定义的…...
C++小小复习一下
类,对象,成员变量,成员函数 特点:面向对象程序设计---因为要创建对象来调用类里面的函数或者成员变量 比如你的对象是一个生物-人:他会有自己的一些属性:身高,体重,性别等…...
JavaWeb学习(4)(四大域、HttpSession原理(面试)、SessionAPI、Session实现验证码功能)
目录 一、web四大域。 (1)基本介绍。 (2)RequestScope。(请求域) (3)SessionScope。(会话域) (4)ApplicationScope。(应用域) (5)PageScope。(页面域) 二、Ht…...
quartz 架构详解
Quartz是一个开源的作业调度框架,完全由Java编写,主要用于定时任务的调度和管理。Quartz的架构主要包括以下几个核心组件: 1.调度器(Scheduler):调度器是Quartz的核心组件,负责管理Qua…...
Redis安装和Python练习(Windows11 + Python3.X + Pycharm社区版)
环境 Windows11 Python3.X Pycharm社区版 思路 1 github下载redis压缩包 ,安装并启动redis服务,在Pycharm中运行python程序,连接redis服务,熟悉redis的使用和巩固python语言。 2 python开发环境的搭建参考 https://mp.csdn.…...
明年 iPhone 将搭载苹果自研 5G 基带芯片
明年 iPhone 将搭载苹果自研 5G 基带芯片 据彭博社记者 Mark Gurman 透露,苹果首款自主研发 5G 基带芯片即将面世。 苹果首款自研 5G 基带芯片将命名为「Sinope」,将应用在 2025 年发布的 iPhone SE、iPhone 17 Slim 版以及低端系列的 iPad 系列。「Si…...
1.1 Beginner Level学习之“编写简单的发布服务器和订阅服务器”(第十二节)
学习大纲: 1. 编写发布服务器节点 在ROS中,**节点(Node)**是与ROS网络通信的基本单位。在这个部分,我们将创建一个简单的发布节点(talker),它会不断向话题(topic&#x…...
C语言 字符串操作函数
strncpy() 用于将一个字符串的一部分拷贝到另一个字符串中。 char* strncpy(char* destination, const char* source, size_t num);参数:destination 是目标字符串的指针,表示将要拷贝到的位置source 是源字符串的指针,表示要拷贝的字符串num…...
论文概览 |《Cities》2024.07 Vol.150(上)
本次给大家整理的是《Cities》杂志2024年07月第150期的论文的题目和摘要,一共包括90篇SCI论文!由于论文过多,我们将通过两篇文章进行介绍,本篇文章介绍第1--第45篇论文! 论文1 Spatiotemporal infection dynamics: Linking indiv…...
查看Windows系统上的Redis服务器是否设置了密码
查看 Redis 配置文件 1.找到 Redis 配置文件: 通常Redis配置文件名为 redis.windows.conf 或 redis.conf,它位于Redis安装目录中。 2.打开配置文件: 使用文本编辑器(如Notepad、VS Code等)打开该文件。 3.查找 re…...
30天学会Go--第6天 GO语言 RESTful API 学习与实践
30天学会Go–第6天 GO语言 RESTful API 学习与实践 文章目录 30天学会Go--第6天 GO语言 RESTful API 学习与实践一、 RESTful API 的设计原则1.1 RESTful API 的核心概念1.2 RESTful API 的 URL 设计1.3 RESTful API 的数据格式 二、 实现 RESTful API2.1 定义数据模型2.2 实现…...
数据分析特征标准化方法及其Python实现
数据分析特征标准化方法及其Python实现 1、概述 在数据分析中,对特征进行标准化主要是: 1、消除量纲影响 不同特征可能具有不同的量纲和数量级。 例如,一个特征可能是以米为单位的长度,而另一个特征可能是以秒为单位的时间。直接使用这些具有不同量纲的原始数据进行分析…...
【推导过程】常用共轭先验分布
文章目录 相关教程相关文献常用共轭先验分布预备知识贝叶斯统计后验分布的计算 正态均值(方差已知)的共轭先验分布是正态分布二项分布中的成功概率 θ 的共轭先验分布是贝塔分布正态均值(方差已知)的共轭先验分布是倒伽玛分布 作者:小猪快跑 基础数学&计算数学&…...
notepad++安装教程(超详细)
1.下载地址(可以私信博主) https://notepad-plus.en.softonic.com/download 2.解压安装...
Django快速入门
目录 1 创建django工程2 运行django3 Django工程目录详解4 开始一个app5 CBV和FBV6 使用模板7 使用模板语言8 自定义simple_tag Django 是用 Python 写的一个自由和开放源码 web 应用程序框架。 web框架是一套组件,能帮助你更快、更容易地开发web站点。当你开始构建…...
ISO45001职业健康安全管理体系认证流程
前期准备 领导决策:企业高层领导需认识到实施 ISO 45001 体系的重要性和必要性,做出认证决策,并承诺提供必要的资源支持。成立工作小组:由企业各相关部门人员组成工作小组,明确各成员的职责和分工,确保工作…...
Elasticsearch一分钟
参考 FST有穷状态转换器/咆哮位图/增量缩紧 Es技术难点 架构...
MFC中如何创建一个非模态对话框
对话框是编程中常用的一个控件,非模态对话框与用户交互更加友好,用户不必关闭对话框就能进行其他操作,比如拷贝黏贴,对比数据,执行其他命令。 由于无模态对话经常使用,且用法类似,因此我把它写…...
【设计模式】单例模式 在java中的应用
文章目录 引言什么是单例模式单例模式的应用场景单例模式的优缺点优点缺点 单例模式的基本实现饿汉式单例模式懒汉式单例模式双重检查锁定静态内部类枚举单例 单例模式的线程安全问题多线程环境下的单例模式线程安全的实现方式1. **懒汉式单例模式(线程不安全&#…...
北京2024年CSP-S/J 及NOIP游记
北京2024年CSP-S/J 及NOIP游记 2024.9 开学2024.9 CSP-S12024.9 停课2024.10假期 误入歧途2024.10 CSP-S2 冲刺 2024.9 开学 开学升入初三,9月的前半个月一直在搞文化课(把文化课搞得风生水起),经历了1天的校运动会(摆…...
vue 纯前端对接阿里云oss文件上传封装,支持批量多文件上传,大文件上传时拿到上传进度。
使用阿里云上传先看官方文档(阿里云官方文档) 我这边只做了简单上传和分片上传,也包含了粘贴上传和拖拽上传。 1.首页先安装 npm i ali-oss2.在utils下创建uploadOss.js const OSS require(ali-oss) import { getOsstoken } from /api/in…...
YOLO系列发展历程:从YOLOv1到YOLO11,目标检测技术的革新与突破
文章目录 前言一、YOLOv1:单阶段目标检测的开端二、YOLOv2:更精准的实时检测三、YOLOv3:阶梯特征融合四、YOLOv4:性能和速度的新平衡五、YOLOv5:易用性和扩展性的加强六、YOLOv6:工业部署的利器七、YOLOv7&…...
认识Java中的异常(半成品)
1.异常的概念与体系结构 1.1在Java中,将程序执行过程中发生的不正常行为称为异常.比如 1.算数异常 public class Main1 {public static void main(String[] args){System.out.println(10/0);} } //异常信息为:Exception in thread "main" java.lang.ArithmeticExc…...
Sqoop 指令语法手册
目录 help指令list-databases参数描述示例 codegen参数描述 Sqoop create-hive-table参数描述 eval参数描述 Export参数描述 import参数描述 import-all-tables参数描述 import-mainframe参数描述 job参数描述 list-tables参数描述 merge参数描述 help指令 sqoop help 下面的S…...
网络安全 - SQL Injection
1.1.1 摘要 日前,国内最大的程序员社区CSDN网站的用户数据库被黑客公开发布,600万用户的登录名及密码被公开泄露,随后又有多家网站的用户密码被流传于网络,连日来引发众多网民对自己账号、密码等互联网信息被盗取的普遍担忧。 网络…...
spi 发送与接收 移位写法
spi _tx 发送模块 片选信号cs可以在top顶层控制模块产生 timescale 1ns / 1psmodule spi_rom#(parameter SIZE 8 )(input wire clk ,input wire rst_n,input wire [SIZE-1:0] data ,input wire …...
MyBatis关联映射
目录 一、什么是关联注解? 二、数据库建表 1.学生表 2.教师表 三、一般查询 (1)创建StudentTeacher类 (2)mapper层 (3)Dao接口 (4)Test类 (5&#x…...
通过华为鲲鹏认证的软件产品如何助力信创产业
软件通过华为鲲鹏认证与信创产业有着密切的联系。鲲鹏认证是华为推动信创产业发展的一项重要举措,通过该认证,软件可以在华为的生态系统中实现更好的兼容性和性能优化,从而推动信创产业的全面发展和国产化替代。 鲲鹏认证的定义和重要性 鲲…...
陈志刚解读:国家数据基础设施建设解读(附下载)
本期分享陈志刚解读:国家数据基础设施建设解读,从背景意图、概念内涵、发展愿景与总体功能、总体架构、重点方向、算力底座、网络支撑、安全防护和组织保障十个方面展开,共52页ppt。 加入星球可获取完整版资料 篇幅限制,部分内容…...
QT 中 sqlite 数据库使用
一、前提 --pro文件添加sql模块QT core gui sql二、使用 说明 --用于与数据库建立连接QSqlDatabase--执行各种sql语句QSqlQuery--提供数据库特定的错误信息QSqlError查看qt支持的驱动 QStringList list QSqlDatabase::drivers();qDebug()<<list;连接 sqlite3 数据库 …...
VPN设备
定义: 虚拟专用网络指的是在公用网络上建立专用网络的技术。之所以称为虚拟网主要是因为整个VPN网络的任意两个节点之间的连接并没 有传统专网所需的端到端的物理链路,而是架构在公用网络服务商所提供的网络平台之上的逻辑网络,用户数据在逻辑链路中传输…...
centos部署SkyWalking并在springcloud项目中用法举例
文章目录 场景SkyWalking介绍部署部署Storage [单机版Elasticsearch]部署SkyWalking OAP [下载地址](https://skywalking.apache.org/downloads/#SkyWalkingAPM)部署SkyWalking Java AgentspringCloud 使用举例 场景 SkyWalking是应用性能监控平台,可用于分布式系统…...
[创业之路-186]:《华为战略管理法-DSTE实战体系》-1-为什么UTStarcom死了,华为却活了,而且越活越好?
目录 前言 一、市场定位与战略选择 二、技术创新能力 三、企业文化与团队建设 四、应对危机的能力 五、客户为中心的理念 六、市场适应性与战略灵活性 七、技术创新与研发投入 八、企业文化与团队建设 九、应对危机的能力 前言 UT斯达康(UTStarcom&#…...
算法设计5_分支限界法
分支限界法 分支限界法常以广度优先或以最小耗费(最大效益)优先的方式搜索问题的解空间树,裁剪那些不能得到最优解的子树以提高搜索效率。 步骤: ① 定义解空间(对解编码); ② 确定解空间的树结构; ③ 按BFS等方式搜索: a.每个活…...
【设计模式系列】状态模式(二十三)
一、什么是状态模式 状态模式(State Pattern)是一种行为设计模式,其核心目的是管理一个对象在其内部状态改变时的行为变化,其核心理念是将对象的行为和状态分离。这种模式通过将每个状态相关的行为封装在独立的类中,使…...
github创建发布分支
创建一个名为 latest 的分支,并将其作为稳定版本分支。以下是操作步骤: 1. 创建 latest 分支 首先,确保你在 master 分支(或当前的稳定版本分支)上,并且已经提交了所有更改。然后,你可以创建一…...
【Linux】网络服务
声明,以下内容均学习自《Linux就该这么学》一书 1、创建网络会话 Linux系统使用NetworkManager提供网络服务,它是一种动态管理网络配置的守护进程,能够让网络设备保持连接状态。 nmcli nmcli是一款基于命令行的网络配置工具,它…...
错题:Linux C语言
题目:手写代码:判断一个数(int类型的整数)中有有多少1 题目:手写代码:判断一个数(转换成二进制表示时)有几个1 #include <stdio.h> int main(int argc, const char *argv[]) { //判断一个数…...
机器学习期末速成
文章参考自B站机器学习期末速成课 本文仅作者个人复习使用 一、机器学习分类 聚类和分类的区别: 分类:一开始就知道有哪些类别 聚类:一开始不知道有哪些类别 损失函数:简单来说就是你预测出来的结果和真实值的差距。 0-1损失函数…...
【学习总结|DAY015】Java面向对象高级-抽象类、接口
引言 在今天的课程中,我们详细探讨了 Java 编程语言的几个核心特性:多态、final 关键字、抽象类和接口。这些概念是面向对象编程的基础,对于构建健壮、可维护的应用至关重要。本文将通过具体的例子和解释帮助大家更好地掌握这些知识点。 一…...