Linux下的多线程编程:原理、工具及应用(2)

news2024/12/26 13:05:22

                                               🎬慕斯主页修仙—别有洞天

                                              ♈️今日夜电波:Flower of Life—陽花

                                                                0:34━━━━━━️💟──────── 4:46
                                                                    🔄   ◀️   ⏸   ▶️    ☰  

                                      💗关注👍点赞🙌收藏您的每一次鼓励都是对我莫大的支持😍


目录

理解互斥锁

前置知识

通过伪代码进行理解

死锁

线程同步的概念

生产者消费者模型

概述

如何理解CP问题?

再次理解条件变量


理解互斥锁

        通过上一篇对于互斥锁操作的基本理解,现在我们从底层理解一下互斥锁的原理:

前置知识

        1、为了实现互斥锁操作,大多数体系结构都提供了swap或exchange指令,该指令的作用是把寄存器和内存单元的数据相交换,由于只有一条指令,保证了原子性
        2、从上面对于锁的理解,我们可以知道,锁其实是一个自定义的结构体类型。现在我们可以先这样简单的理解一下这个结构体类型,真正的结构体类型肯定是包涵很多安全属性之类的:

struct 
{
  int mutex=1;
}

        3、寄存器硬件在CPU内部只有一套,但是寄存器的内容每一个线程都有一份,拥有属于自己的上下文!

通过伪代码进行理解

        知道了上面的前置知识后,我们通过以下的伪代码真正的理解:

lock:

        注意上面的汇编语句都是原子性的!可以看到第一段movb $0,%a1表示为将数值0移动到寄存器 %a1 的最低字节,就是初始化%a1为0.然后通过xchgb %a1,mutex交换寄存器和内存单元中的数据。由于我们的锁的定义实际上就是一个自定义类型的定义,因此,他当然是存储在内存中的啦!我们可以通过以下图示来理解:

        接着继续理解,下面是一段if判断的伪代码,判断al寄存器中的内容是否大于0,如果我们的线程还在时间片内,那么他就是大于0的会返回0,当时间片用完,那么我们的其他寄存器等会保存上下文。新的进程进来了,同样有锁,需要初始化al为0,然后交换内存中的数据,但是!重要的来了,此时内存中的mutex是0!我们换后还是0!,此时进行if判断,就会挂起等待!!!这就是加锁的底层原理!

unlock:

        解锁可以看到movb $1,%a1就是初始化%a1为1,然后唤醒被因Mutex挂起等待的线程即可。

死锁

        死锁是指在一组进程中的各个进程均占有不会释放的资源,但因互相申请被其他进程所站用不会释放的资源而处于的一种永久等待状态。

###死锁四个必要条件

互斥条件:一个资源每次只能被一个执行流使用

请求与保持条件:一个执行流因请求资源而阻塞时,对已获得的资源保持不放

不剥夺条件:一个执行流已获得的资源,在末使用完之前,不能强行剥夺

循环等待条件:若干执行流之间形成一种头尾相接的循环等待资源的关系

###避免死锁

破坏死锁的四个必要条件

加锁顺序一致

避免锁未释放的场景

资源一次性分配

线程同步的概念

###条件变量

当一个线程互斥地访问某个变量时,它可能发现在其它线程改变状态之前,它什么也做不了。

例如一个线程访问队列时,发现队列为空,它只能等待,只到其它线程将一个节点添加到队列中。这种情况就需要用到条件变量。


####同步概念与竞态条件

同步:在保证数据安全的前提下,让线程能够按照某种特定的顺序访问临界资源,从而有效避免饥饿问题,叫做同步。

竞态条件:因为时序问题,而导致程序异常,我们称之为竞态条件。在线程场景下,这种问题也不难理解

生产者消费者模型

概述

        生产者消费者模型,我们可以这样理解:有一间商店,消费者要去买东西,生产者要供货。而在这之间我们可以将生产者与消费者分别理解为线程,而商店理解为内存空间(基于特定空间的数据结构或者容器),而这个商店是用于进行执行流间数据的传递的!可以理解为临界资源!在这个模型中,我们需要保证生产消费的过程是安全的!因此我们需要遵守以下的原则:可以简称为“321原则”。

1、3种关系:(本质就是用锁&&条件变量维护)

生产者与生产者之间是什么关系?竞争—互斥

消费者与消费者之间是什么关系?竞争—互斥

生产者与消费者之间是什么关系?互斥&&同步

2、2种角色

生产者(1 or n)、消费者(1 or n) --线程或者进程

3、1个交易场所

内存空间

如何理解CP问题?

        在生产者消费者模型中,CP问题通常指的是生产者和消费者之间的同步问题,即如何保证生产者不会在缓冲区满时加入数据,消费者也不会在缓冲区空时取出数据。这个问题可以通过使用多线程编程中的同步机制来解决。具体来说,有以下几个方面:

  1. 共享缓冲区:生产者和消费者共享一个固定大小的缓冲区,生产者向其中放入数据,消费者从其中取出数据。
  2. 同步机制:为了避免生产者在缓冲区满时继续生产数据,以及消费者在缓冲区空时继续消费数据,需要使用同步机制。常见的同步机制包括互斥锁(mutex)和条件变量(condition variable)。互斥锁用于保护共享资源,防止同时读写;条件变量则用于实现线程间的等待和通知机制。
  3. 状态一致性:需要确保在任何时刻,缓冲区的数据状态都是一致的。这意味着在消费者取出数据后,必须及时更新缓冲区的状态,以防止其他消费者错误地认为还有数据可取。
  4. 生产者限制:生产者在生产数据时,需要检查缓冲区是否已满。如果缓冲区已满,生产者必须等待,直到消费者取出数据并通知生产者可以继续生产。
  5. 消费者限制:消费者在消费数据时,需要检查缓冲区是否为空。如果缓冲区为空,消费者必须等待,直到生产者放入数据并通知消费者可以继续消费。
  6. 编码实践:在实现生产者-消费者模型时,需要注意避免竞态条件和死锁。正确的使用同步机制是解决这些问题的关键。
  7. 实际应用:生产者-消费者模型在分布式系统、并发编程和实时系统中非常常见,它是理解和解决并发问题的基础模型之一。

再次理解条件变量

        生产者消费者模型会有数据不一致的问题,上面提到为了满足线程同步,光加锁是不够的,可能会有饥饿的问题。因此,我们需要定义“条件变量”来让线程不做无效的锁申请,执行具有顺序。我们可以先简单的用以下的结构体先理解条件变量:

struct cond
{
  //条件是否就绪
  int flag;
  //维护一个线程队列
  tcb_queue;
}


                      感谢你耐心的看到这里ღ( ´・ᴗ・` )比心,如有哪里有错误请踢一脚作者o(╥﹏╥)o! 

                                       

                                                                        给个三连再走嘛~  

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

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

相关文章

【C++ RB树】

文章目录 红黑树红黑树的概念红黑树的性质红黑树节点的定义红黑树的插入代码实现总结 红黑树 AVL树是一颗绝对平衡的二叉搜索树,要求每个节点的左右高度差的绝对值不超过1,这样保证查询时的高效时间复杂度O( l o g 2 N ) log_2 N) log2​N),…

钉钉小程序 - - - - - 如何通过一个链接打开小程序内的指定页面

方式1 钉钉小程序 scheme dingtalk://dingtalkclient/action/open_mini_app?miniAppId123&pagepages%2Findex%2Findex%3Fx%3D%25E4%25B8%25AD%25E6%2596%2587 方式2 https://applink.dingtalk.com/action/open_mini_app?type2&miniAppIdminiAppId&corpIdcorpId&…

MySQL行锁核心知识介绍

MySQL的行锁是数据库中用于控制并发访问的一种机制。它允许在数据库的行级别上实现锁定,从而允许多个事务同时修改不同行的数据,而不会相互干扰。这种锁机制可以提高数据库的并发性能,减少锁争用,提高事务的吞吐量。在本教程中&am…

一周学会Django5 Python Web开发-Jinja3模版引擎-安装与配置

锋哥原创的Python Web开发 Django5视频教程: 2024版 Django5 Python web开发 视频教程(无废话版) 玩命更新中~_哔哩哔哩_bilibili2024版 Django5 Python web开发 视频教程(无废话版) 玩命更新中~共计35条视频,包括:2024版 Django5 Python we…

.Net Core 中间件验签

文章目录 为什么是用中间件而不是筛选器?代码实现技术要点context.Request.EnableBuffering()指针问题 小结 为什么是用中间件而不是筛选器? 为什么要用中间件验签,而不是筛选器去验签? 1、根据上图我们可以看到,中间件在筛选器之…

Selenium控制已运行的Edge和Chrome浏览器——在线控制 | 人机交互(详细启动步骤和bug记录)

文章目录 前期准备1. 浏览器开启远程控制指令(1)Edge(2)Chrome 2. 执行python代码(1)先启动浏览器后执行代码(2)通过代码启动浏览器(3)Bug问题记录1&#xff…

前端和后端权限控制【笔记】

前端权限设置【笔记】 前言版权推荐前端权限设置需求效果实现资源 后端权限控制1.给所有前端请求都携带token2.添加拦截器3.配置到WebMvcConfiguration4.更多的权限验证 最后 前言 2024-3-15 18:27:26 以下内容源自《【笔记】》 仅供学习交流使用 版权 禁止其他平台发布时删…

鸿蒙Harmony应用开发—ArkTS声明式开发(容器组件:FormLink)

提供静态卡片交互组件,用于静态卡片内部和提供方应用间的交互,当前支持router、message和call三种类型的事件。 说明: 该组件从API Version 10开始支持。后续版本如有新增内容,则采用上角标单独标记该内容的起始版本。 该组件仅可…

Gitlab CI/CD 自动化打包部署前端(vue)项目

一、虚拟机安装 1.vmware下载 2.镜像下载 3.Ubuntu 4.新建虚拟机 一直点下一步,直到点击完成。 5.分配镜像 二、Gitlab CI/CD 自动化部署项目 1.配置GitLab CI/CD: A.在你的Vue.js项目中,创建一个名为.gitlab-ci.yml的文件&#xff0…

Javaweb--CSS

一:概述 CSS (Cascading Style Sheet(层叠样式表))是一门语言,用于控制网页表现。 W3C标准规定了网页是由以下组成: 结构:HTML 表现:CSS 行为:JavaScrip…

【计算机网络】UDP/TCP 协议

TCP 协议 一、传输层1. 再谈端口号2. 端口号范围划分3. 进程和端口号4. netstat5. pidof 二、UDP 协议1. UDP 协议端格式(报文)2. UDP 的特点3. 面向数据报4. UDP 的缓冲区 三、TCP 协议1. 认识 TCP2. TCP 协议段格式(1)4 位首部长度(2&#…

(三)丶RabbitMQ的四种类型交换机

前言:四大交换机工作原理及实战应用 1.交换机的概念 交换机可以理解成具有路由表的路由程序,仅此而已。每个消息都有一个称为路由键(routing key)的属性,就是一个简单的字符串。最新版本的RabbitMQ有四种交换机类型&a…

用真值表、逻辑表达式和卡诺图来表示数字电路中的逻辑关系

真值表(Truth Table) 真值表是一种直观的方式,通过列出所有可能的输入值及其对应的输出值来表示逻辑关系。以下是使用真值表表示逻辑关系的步骤: 1. 确定输入变量:列出数字电路中所有的输入变量。 2. 定…

CART决策树暴力生成风控规则(Python代码)

上一篇我们介绍了决策树节点信息更新的方法风控规则的决策树可视化(升级版),以辅助我们制定风控规则,可视化的方法比较直观,适合做报告展示,但分析的时候效果没那么高。 本篇我们介绍一种通过决策树自动挖…

基于openresty构建运维工具链实践

本文字数:4591字 预计阅读时间:25 01 导读 如今OpenResty已广泛被各个互联网公司在实际生产环境中应用,在保留Nginx高并发、高稳定等特性基础上,通过嵌入Lua来提升在负载均衡层的开发效率并保证其高性能。本文主要介绍接口鉴权、流…

【Java】容器|Set、List、Map及常用API

目录 一、概述 二、List 1、List的常用API 2、ArrayList 3、List遍历 三、Set 1、Set的常用方法: 2、HashSet 3、遍历集合: 四、Map 1、Map常用API 2、HashMap 3、遍历Map 五、迭代器 一、概述 在Java中所有的容器都属于Collection接口下的内容 1…

D-泛醇(右泛醇)应用领域广泛 我国市场参与者众多

D-泛醇(右泛醇)应用领域广泛 我国市场参与者众多 D-泛醇又称右泛醇、原维生素B5,化学式为C9H19NO4,为泛醇的右旋异构体。D-泛醇外观呈无色粘稠或透明液体,微含臭味,可溶于甲醇、乙醇、水和丙二醇。D-泛醇综…

react native 实现自定义底部导航与路由文件配置

首先先把需要的一些库引入 yarn install react-navigation/native yarn install react-native-screens react-native-safe-area-context yarn install react-navigation/native-stack yarn add react-navigation/bottom-tabs 创建路由文件及四个底部导航页面 router文件下的bot…

MATLAB:一些杂例

a 2; b 5; x 0:pi/40:pi/2; %增量为pi/40 y b*exp(-a*x).*sin(b*x).*(0.012*x.^4-0.15*x.^30.075*x.^22.5*x); %点乘的意义 z y.^2; %点乘的意义 w(:,1) x; %组成w,第一列为x w(:,2) y; %组成w,第二列为y w(:,3) z; %组成w,第三列为z…

大规模C++程序设计 -- 基本规则

文章目录 基本规则概述成员数据访问全局命名空间全局数据自由函数枚举类型、typedef和常量数据预处理宏头文件中的名称 包含卫哨包含冗余卫哨文档标识符命名规则 基本规则 概述 任何精美的艺术不仅来源于创造,而且来自于规范。编程也是如此。C是易总大型语言&…