liunx线程互斥

news2024/11/27 12:51:20

临界资源和临界区

临界资源:多线程执行流共享的资源就叫临界资源。

临界区:每个线程中,访问临界区的代码,就叫临界区。

互斥:任何时候,互斥保证只有一个执行流进入临界区,访问临界资源,通过对临界资源起到保护作用

原子性:不会被任何调度机制打断的操作,该操作有两态,要么完成,要么未完成。


  局部变量和共享变量

  • 局部变量:变量的地址空间在线程栈空间内,变量归属于单个线程,其他线程无法看到这个变量
  • 共享变量:变量可以在线程间共享,完成线程之间的交互

当多个线程共发操作共享变量,会出现问题!

例如:对g_val全局变量进行--操作,在汇编层面会被分成三步:

  1. load:从内存中读取数据到寄存器中
  2. update:更新寄存器的值,执行-1操作
  3. store:将新值,将寄存器写回共享变量g_val的内存地址

所以在一个线程执行三步操作期间,发生线程切换,其他线程对g_val变量进行操作,就会导致问题。问题就在于:共享资源没有被保护起来

保护临界资源的方法

  • 代码需要互斥行为,当代码进入临界区执行时,不允许其他线程进入该临界区
  • 如果多个线程同时要求执行临界区代码,并且临界区没有线程在执行,那么只允许一个线程进入该临界区
  • 如果线程不在临界区中执行,那么该线程不能阻止其他线程进入临界区

方法就是:需要在临界区之间加锁

互斥锁操作的原理

为了实现互斥锁操作,大多数体系结构都提供了swap或exchange指令,该指令的作用把寄存器和内存单元的数据相交换,由于只有一条指令,保证了原子性,即使是多处理器平台,访问内存的,总线周期也有先后,一个处理器的交换指令执行时另一个处理器的指令只能等待总线周期。

交换的本质:所有线程在争锁时,只有"1",交换是一条汇编-->原子的

lock操作:

  • %al寄存器值变成0
  • 交换%al寄存器值和内存的值(mutex的值变成0,%al的值变成1)
  • 判断%al寄存器的值(如果此时发生线程切换,原线程会把%al的值带走,新线程使用%al的寄存器和mutex的0交换,新线程判断false) 
  • goto会重新执行上面代码,重新让%al=0

unlock操作:

  • 将mutex=1
  • 唤醒等待mutex的线程,让他们竞争锁

可重入和线程安全

  • 线程安全:多个线程并发同一段代码时,不会出现不同的结果。常见于对全局变量和静态变量进行操作,但是在没有锁保护的情况下,会出现该问题
  • 重入:同一个函数被不同的执行流,当前一个流程还没有执行完,还有其他的执行流再次进入,我们称之为重入。一个函数在重入的情况下,运行情况不会出现任何问题,则称为函数是可以重入的,否则,是不可重入函数

常见线程不安全的情况

  1. 不保护共享变量的函数
  2. 函数状态随着调用,状态发生变化的函数
  3. 返回指向静态变量的指针的函数
  4. 调用线程不安全的函数

常见不可以重入的情况

  1. 调用了malloc/free函数,因为malloc函数是用全局链表管理的
  2. 调用了标准的I/O库函数,标准I/O库的实现都是以不可重入的方式使用全局数据结构

 常见可重入的情况

  • 不使用全局变量或静态变量
  • 不使用malloc或者new开辟出来的空间
  • 不调用不可重入函数
  • 不返回静态或全局数据,所有数据都由函数的调用者提供
  • 使用本地数据,或者通过制作全局数据本地拷贝来保护全局数据

可重入与线程安全联系

  • 函数是可重入的,那线程就是安全的
  • 函数是不可重入的,那不能多个线程使用,有可能引发线程安全
  • 如果函数有全局变量,那么函数既不是线程安全的也不是可重入的
  • 可重入函数是线程安全的一种
  • ‘线程安全不一定是可重入的,但是可重入的一定是线程安全的
  • 如果对临界资源上锁,那么这个函数是线程安全的,但是如果这个函数的锁没有被释放会产生死锁,因此是不可重入的

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

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

相关文章

华为eNSP:端口安全

一、什么是端口安全 端口安全是指保护计算机端口免受未经授权的访问、攻击或滥用的一种措施。计算机上的每个服务或应用程序都依靠特定的端口进行通信。端口安全的目的是限制对计算机端口的访问,确保只有经过授权的用户或服务可以使用这些端口。通过配置防火墙、访…

C/C++(六)多态

本文将介绍C的另一个基于继承的重要且复杂的机制,多态。 一、多态的概念 多态,就是多种形态,通俗来说就是不同的对象去完成某个行为,会产生不同的状态。 多态严格意义上分为静态多态与动态多态,我们平常说的多态一般…

VulkanTutorial(1·环境搭建,渲染流程简述)

介绍: 与OpenGL,WebGL和Direct3D等API((Application Programming Interface, 应用程序编程接口))相比,valkan更偏向于底层,有更多的GPU控制接口,因此它有更好的性能和更小的驱动开销&#xff0…

【Python数据可视化】利用Matplotlib绘制美丽图表!

【Python数据可视化】利用Matplotlib绘制美丽图表! 数据可视化是数据分析过程中的重要步骤,它能直观地展示数据的趋势、分布和相关性,帮助我们做出明智的决策。在 Python 中,Matplotlib 是最常用的可视化库之一,它功能…

【论文+源码】基于spring boot的垃圾分类网站

创建一个基于Spring Boot的垃圾分类网站涉及多个步骤,包括环境搭建、项目创建、数据库设计、后端服务开发、前端页面设计等。下面我将引导您完成这个过程。 第一步:准备环境 确保您的开发环境中安装了以下工具: Java JDK 8 或更高版本Mav…

python装饰器的另类用法

在对pyverilog源码进行单步调试时,遇到一个很奇怪的现象,被装饰器装饰的方法t_LINECOMMENT没有主动调用,但装饰器TOKEN中的内嵌函数set_regex却被调用了。 ## lexer.pyfrom ply.lex import *class VerilogLexer(object):linecomment r"…

C++【string类的使用】(上)

文章目录 1. 为什么要学习string类2. 标准库的string类2.1 string的构造函数(1)无参构造(重点)(2)用字符串初始化(重点)(3)用字符串的前n个字符初始化(4)拷贝…

常见ElasticSearch 面试题解析(上)

前言 ElasticSearch是一个基于Lucene的搜索服务器。它提供了一个分布式多用户能力的全文搜索引擎,基于RESTful web接口。Elasticsearch是用Java语言开发的,并作为Apache许可条款下的开放源码发布,是一种流行的企业级搜索引擎。ElasticSearch…

直播间“饕餮盛宴”的背后,是“他经济”正在冒头

最近,一个有意思的现象逐渐露出了苗头。 今年“双11”第一轮尾款开启支付的当晚,罗永浩的直播间上演了一出别样的“饕餮盛宴”。直播开场后,iphone16系列、可口可乐(含糖、无糖300ml)10秒售罄,索尼PS5、沃…

hive on tez 指定队列后任务一直处于running状态

如上图所示一直处于running状态&#xff0c;查看日志发现一直重复弹出同一个info&#xff1a; 2024-10-18 16:57:32,739 [INFO] [AMRM Callback Handler Thread] |rm.YarnTaskSchedulerService|: Allocated: <memory:0, vCores:0> 释义: 当前应用程序没有分配到任何内存…

wordcloud 字体报错

wordcloud 字体报错 词云库报错&#xff1a;Only supported for TrueType fonts字体文件问题pillow版本的问题wordcloud版本问题&#xff08;我的最终解决方案&#xff09; 词云库报错&#xff1a;Only supported for TrueType fonts 字体文件问题 解决方法 写绝对路径 &…

教程分享!超简单的低功耗4G模组LCD应用示例!看过来~

低功耗4G模组LCD应用是物联网技术中的一部分知识&#xff0c;在未来的学习和实践中&#xff0c;我们还将接触到更多前沿的技术和理念。让我们一起努力&#xff0c;探索科技的无限可能&#xff0c;为我们的生活带来更多便利与惊喜&#xff01;希望本文能为您提供一些帮助&#x…

Cisco WLC 9800 - HA SSO with Ether-channel

本文将记录如何配置HA SSO以及Ethernet Channel。 1.拓扑情况 本文的内容基于如下的Topo进行。 2.准备工作 两台WLC的型号必须一样&#xff1b;两台WLC必须使用一样的软件版本&#xff1b;需要准备好使用的IP地址&#xff1a;两个用于WLC的管理地址&#xff08;WMI&#xff…

串口通讯编程示例之串口编写程序

使用open()函数打开串口设备 首先使用open()函数打开串口设备/dev/ttymxc6&#xff0c;设备使用了O_RDWR | O_NOCTTY | O_NDELAY标志&#xff0c;分别代表以读写方式打开、不让设备成为控制终端且设置非阻塞模式&#xff0c;也就是当无法打开设备时&#xff0c;不会在原地等待&…

【博客节选】Unity角色异常抖动问题排查

本文截取自本人文章 &#xff1a;【Unity实战笔记】第二一 基于状态模式的角色控制——以UnityChan为例 发现出现角色抖动问题 尝试解决方法&#xff1a; 跳跃的loop time不要勾选&#xff1b; 相机aim添加垂直阻尼 还是不行&#xff0c;仔细查看是位移时震颤。 UnityCha…

HCIP-HarmonyOS Application Developer 习题(十三)

&#xff08;多选&#xff09;1、在设计应用框架的过程中&#xff0c;我们常用的界面应用框架有哪些? A、启动页 B、详情页 C、列表视图 D、网格视图 答案&#xff1a;ABCD 分析&#xff1a; &#xff08;多选&#xff09;2、触摸屏以触控的方式进行输入。它可以支持以下哪些…

OpenIPC开源FPV之Ardupilot配置

OpenIPC开源FPV之Ardupilot配置 1. 源由2. 问题3. 分析3.1 MAVLINK_MSG_ID_RAW_IMU3.2 MAVLINK_MSG_ID_SYS_STATUS3.3 MAVLINK_MSG_ID_BATTERY_STATUS3.4 MAVLINK_MSG_ID_RC_CHANNELS_RAW3.5 MAVLINK_MSG_ID_GPS_RAW_INT3.6 MAVLINK_MSG_ID_VFR_HUD3.7 MAVLINK_MSG_ID_GLOBAL_P…

千万不要小看SD3.5!最强模型全家桶来了!

一、SD3.5 的登场 Stability AI 推出的 SD3.5 引起了广泛关注。它直接开源了三个模型&#xff0c;包括 Large 和 Large Turbo&#xff0c;Medium 将于 29 号发布&#xff0c;并且这三个型号都可以商用。 &#xff08;一&#xff09;模型版本介绍 模型版本参数量特点分辨率范围S…

《A complete telomere-to-telomere assembly of the maize genome》方法总结

研究背景 完整的T2T基因组组装一直是基因组研究的长期追求。 研究方法 通过生成高深度覆盖的超长 Oxford Nanopore Technology (ONT) 和 PacBio HiFi 测序数据&#xff0c;报道了玉米的完整基因组组装。 每条染色体均以单一contig的形式完整覆盖。 结果概述 基因组特征&am…

vue3中mitt和pinia的区别和主要用途,是否有可重合的部分?

在 Vue 中&#xff0c;Mitt 和 Pinia 是两个不同的工具&#xff0c;它们的主要用途和功能有所不同&#xff0c;但在某些方面也存在重合的部分。 区别 Mitt&#xff1a; Mitt 是一个简单而强大的事件总线库&#xff0c;用于在组件之间进行事件的发布和订阅。 它提供了一种简洁…