Linux/多线程的同步与互斥

2023-11-14

线程安全:多个执行流对资源进行争抢访问,但不会产生数据二义性
线程安全的实现:同步,互斥
同步:通过条件判断实现对临界资源访问的合理性
互斥:通过同一时间对临界资源的唯一访问,实现对临界资源访问的安全性

互斥锁

互斥的实现:互斥锁

在多任务处理的操作系统中,多个执行流可能同时要使用某个数据,就假如我们现实中有一台打印机,有许多人要使用,如果不加以控制,比如说排队,上一个人还没有使用完下一个人就是用,打印出来的东西肯定就是混乱的。
在线程中也有一个处理方式,叫做互斥锁。
互斥锁是一种简单的加锁的方式来控制对临界资源的访问,互斥锁只有两种状态:上锁(lock)和解锁(unlock)
互斥锁:互斥锁本身是一个0/1的计数器,描述了一个临界资源的访问状态,每个执行流在访问临界资源之前都需要判断这个临界资源的访问状态,如果不可以访问,则执行流挂起等待,如果可以访问,则让执行流访问临界资源,但在访问期间需要将资源状态改为不可访问状态。这期间如果有其他执行流想要访问,则不被允许。在执行流访问完临界资源退出前会将资源状态改变会可访问状态。

互斥锁特性:
1.原子性:将一个互斥锁的操作定义成原子操作,因为一个互斥锁也相当于一个临界资源,大家都可以访问,在使用时必须保证操作的原子性。
在这里插入图片描述

如果有多个线程同时去获取锁资源,这时Mutex的值判断>0,一个线程在将mutex置0的过程中,另一个线程也可以进入,那么这些线程都会以为自己获得了锁。然而线程在任何时候都可能会被触发导致切换,每个线程运行时,mutex都会加载入cpu,同时访问临界资源,这会导致有多个mutex副本,还是无法保证数据的一致性。
因此一般先将寄存器中的值置为0,线程得到锁后进入寄存器,直接进行一次数据交换,将寄存器中0与Mutex的1交换,操作一次完成,保证了操作的原子性。

唯一性:如果一个线程锁定了一个互斥量,在它解除锁定之前,没有线程可以锁定这个互斥量
非繁忙等待:如果一个线程已经锁定了一个互斥量,另一个线程又试图去锁定这个互斥量,这个线程将会被挂起等待,直到第一个线程解除对互斥量的锁定,第二个线程则被唤醒执行,并锁定这个互斥量。

互斥锁具体的操作流程及接口介绍

  1. 定义互斥锁变量
pthread_mutex_t mutex
  1. 初始化互斥锁变量
pthread_mutex_init(pthread_mutex_t* mutex,pthread_mutexattr_t* attr)
  1. 在访问临界资源前进行加锁访问
pthread_mutex_lock(pthread_mutex_t* mutex)
pthread_mutex_trylock(pthread_mute_t* mutex)
  1. 在临界资源访问结束后进行解锁
pthread_mutex_unlock(pthread_mutex_t* mutex)
  1. 销毁互斥锁
pthread_mutex_destroy(pthread_mutex_t* mutex)

死锁
多个执行流对锁资源进行争抢访问,但是因为访问推进顺序不当,造成互相等待最终导致程序流程无法执行下去,这时候就造成了死锁。

死锁产生的原因

  1. 资源竞争
    如果一个线程先后两次调用了lock,第二次调用时锁已经被占用,那么这个线程会被挂起等待别的线程去释放锁,但是使用锁的是自己并且自己已经被挂起等待,就会一直处于挂起等待状态,造成死锁。
  2. 线程推进顺序不当
    假设线程1使用了锁A,线程2使用了锁B,线程1此时想要去使用锁B会被挂起等待,线程2想要去使用锁A会被挂起等待,于是两个线程都处于挂起等待状态了

死锁产生的条件

  1. 互斥:我使用了锁,别人不能使用锁
  2. 请求与等待:我使用了锁,别人只能等待我解锁才能使用,否则等待
  3. 请求与保持条件:我使用了锁A,我去请求锁B,并不会释放锁A
  4. 环路等待条件:我使用了锁A,请求B锁,另一个人使用了锁B,去请求锁A

为了避免死锁的产生,在使用互斥锁时应该尽量避免同时获得多个锁

同步

条件变量

条件变量:线程在满足资源的访问条件的时候才能去访问资源,否则就挂起线程,直到满足条件后再去唤醒线程
因为条件变量只提供了使线程等待和唤醒线程的接口,因此访问条件是否满足要在我们使用时自行判断。
操作代码
定义条件变量

pthread_cond_t cond;

初始化条件变量

pthread_cond_init(pthread_cond_t* cond,phread_condattr_t* attr)
//cond:条件变量
//attr:属性,一般置NULL

使线程挂起休眠(需要搭配互斥锁一起使用),因为判断条件是否满足的条件本身就是一个临界资源

pthread_cond_wait(pthread_cond_t* cond,pthread_mutex_t* mutex)
//一直等待别人唤醒,不唤醒则一直等待
pthread_cond_timedwait(pthread_cond_t* cond,pthread_mutex_t mutex,struct timespec)
//等待指定时间,不唤醒则时间到了自动唤醒

唤醒线程

pthread_cond_signal(pthread_cond_t* cond)
//唤醒至少一个等待线程
pthread_cond_broadcast(pthread_cond_t* cond)
//唤醒所有等待线程

销毁条件变量

pthread_cond_destroy(pthread_cond_t* cond)

注意:
1.条件变量使用对条件的判断需要使用while语句
2.多个角色线程应该使用多个条件变量

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Linux/多线程的同步与互斥 的相关文章

  • 多线程系列之——事件内核对象

    所有内核对象里面事件内核对象是最简单的一个 它包括一个使用计数 还有两个布尔值 一个布尔值用来表示事件是手动重置事件还是自动重置事件 另一个布尔值表示当前是否处于触发状态 当一个手动重置事件被触发的时候 所有等待该事件的线程都能变成调度状态
  • ps aux 和ps -aux和 ps -ef的选择

    Linux中的ps命令是Process Status的缩写 ps命令用来列出系统中当前运行的那些进程 ps命令列出的是当前那些进程的快照 就是执行ps命令的那个时刻的那些进程 如果想要动态的显示进程信息 就可以使用top命令 要对进程进行监
  • Linux 磁盘与文件系统管理(鸟哥私房菜)

    本文来自 http vbird dic ksu edu tw linux basic 0230filesystem php 第八章 Linux 磁盘与文件系统管理 系统管理员很重要的任务之一就是管理好自己的磁盘文件系统 每个分割槽不可太大也
  • Java堆的自动垂直缩放

    多年以来 java一直是贪婪的应用程序的同义词 这种类型的应用程序在晚上打开冰箱并吞噬所有可用资源 直到崩溃 该行为的主要原因是缺乏一种有效的方式来将操作系统在Java堆中分配且不再使用的内存交还给操作系统 However with the
  • 安装黑苹果双系统专辑贴(持续更新...)

    最近终于开始研究黑苹果 然后浏览了几篇文章贴收集一下 以便需要时随时阅览 和同学们互相学习 零基础篇 1 https blog csdn net a792396951 article details 80230946 2 https zhu
  • 操作系统笔记六(文件管理)

    1 文件逻辑结构 1 1逻辑结构的文件类型 分类 有结构文件 例如 PNG文件 无结构文件 1 2顺序文件 1 3索引文件 2 辅存的存储空间分配 2 1分配方式 连续分配 直接分配连续的存储空间 链接分配 隐式链接 在盘块内指定下一个盘块
  • Linux,Network manager 导致节点异常重启

    推断是Network manager 导致的 原因待查今天在VmWare的虚拟机上装了个测试RAC 又遇到了一个摸不到头绪的问题CRS装好后 一旦登陆图形界面 节点就重启 事情就有这么巧不登陆图形界面 观察了1个小时没问题 一旦登陆后 立刻
  • 55黑马QT笔记之关闭子线程

    55黑马QT笔记之关闭子线程 1 这里为什么要单独写多一篇文章来说线程的关闭呢 主要是想让大家提升印象 养成资源回收的好习惯 任何时候都要想起开辟过的内存回收 这里的关闭子线程上一篇也写到了 就是利用关闭窗口时调用槽函数回收掉 2 具体步骤
  • Java多线程 - 线程池常用容量设置

    线程执行方式 线程的执行是由CPU进行调度的 一个CPU在 同一时刻只会执行一个线程 操作系统利用了时间片轮转的方式 CPU给每个任务都服务一定的时间 然后把当前任务的状态保存下来 再加载下一个任务的状态后 继续服务下一个任务 任务的保存及
  • 使用inet_ntop转换IPv6地址时在macOS和linux上的行为不一样

    下面这段python代码在macOS和linux时运行的结果是不同的 import socket ip socket inet pton socket AF INET6 1 2 3 0 5 6 7 8 print socket inet n
  • 阿里巴巴开发手册-并发处理

    强制 获取单例对象要线程安全 在单例对象里面做操作也要保证线程安全 说明 资源驱动类 工具类 单例工厂类都需要注意 强制 线程资源必须通过线程池提供 不允许在应用中自行显式创建线程 说明 使用线程池的好处是减少在创建和销毁线程上所花的时间以
  • wxwidgets编写多线程程序--wxThread

    细节描述 线程基本上来说是应用程序中一条单独执行的路径 线程有时被称为轻量级进程 但线程与进程的根本不同之处在于不同进程存储空间是相互独立的 而同一进程里的所有线程共享同一地址空间 尽管这使得它更容易共享几个线程间的普通数据 但这也使得它有
  • linux 使用systemctl 启动服务报错: Error: No space left on device

    By default Linux only allocates 8192 watches for inotify which is ridiculously low And when it runs out the error is als
  • 操作系统常见面试题

    1 什么是进程 Process 和线程 Thread 有何区别 进程是具有一定独立功能的程序关于某个数据集合上的一次运行活动 进程是系统进行资源分配和调度的一个独立单位 线程是进程的一个实体 是CPU调度和分派的基本单位 它是比进程更小的能
  • 多线程下载文件(支持暂停、取消、断点续传)

    多线程下载文件 支持暂停 取消 断点续传 多线程同时下载文件即 在同一时间内通过多个线程对同一个请求地址发起多个请求 将需要下载的数据分割成多个部分 同时下载 每个线程只负责下载其中的一部分 最后将每一个线程下载的部分组装起来即可 涉及的知
  • gdb attach 进程调试

    gdb调试正在运行的进程 GDB可以对正在执行的程序进行调度 它允许开发人员中断程序 并查看其状态 之后还能让这个程序正常地继续执行 gdb attach xxxxx xxxxx为利用ps命令获得的子进程process
  • VS2008编译的程序在某些机器上运行提示“由于应用程序配置不正确,应用程序未能启动”的问题...

    VC9编译的程序在没有装过VC9 确切的说是 Net Framework3 5 的机器上运行时 如果提示 由于应用程序配置不正确 应用程序未能启动 重新安装应用程序可能会纠正这个问题 这个错误 那么就说明该程序动态链接了VC9的运行时库 如
  • TaskDecatator用法

    在Spring框架中 TaskDecorator 是一个接口 它可以用来自定义由 ThreadPoolTaskExecutor 或其他任务执行器管理的任务的装饰行为 这通常用于在执行任务之前和之后添加某些上下文相关的行为 比如设置线程上下文
  • 【操作系统xv6】学习记录4-一级页表与二级页表

    占位
  • JUC的常见类

    目录 Callable ReentrantLock Semaphore CountDownLatch JUC 即 java util concurrent 其中存放了一些进行多线程编程时有用的类 Callable Callable是一个接口

随机推荐

  • 硬盘故障时如何强制关机:Input/output error

    如果硬盘可能会出现锁死或坏道的故障 会造成SHELL命令的失效 包括 reboot powoff shutdown 用正常的命令是没法完成重启的 执行这些命令 会出现如下IO报错 reboot bash sbin reboot Input
  • 【微信小程序-0基础入门】项目发布完整流程

    写在前面 上一节讲述了小程序的相关介绍以及账号注册 这一节讲述小程序发布的具体流程 目录 安装开发者工具 小程序项目发布流程 小程序代码的构成 项目结构 1 了解项目的基本组成结构 2 小程序页面的组成部分 小程序代码的构成 JSON 配置
  • Unity游戏开发之游戏动画(模型动画制作及导入)

    一 简单制作3D角色 在stream中下载Fuse软件 在Fuse中制作人物 导出模型为OBJ格式 注意 这里导出目录必须为英文路径 否则只能导出空的OBJ文件 压缩Obj文件为zip格式 打开Mixamo网站 https www mixa
  • 以“信”数智,筑“广”生态:亚信科技CEO高念书受邀出席中国广电数字化赋能大会

    6月30日 由国家广播电视总局指导 中国广电集团主办的中国广电数字化赋能大会在京召开 国家广播电视总局党组成员 副局长杨小伟 工信部总工程师赵志国 中国移动党组成员 副总经理高同庆等出席会议并致辞 中广电移动网络有限公司董事长宋起柱作主题报
  • Golang 程序测试框架

    注意事项 测试用例文件名必须以 test go结尾 如 person test go 测试用例函数必须以Test开头 比如person test go文件中的TestReStore 测试函数的形参必须是t testing T 一个测试用例文
  • stm32(SCCB)+ov7670摄像头输出图像程序

    一 简介 OV7670一般模块指低成本数字输出CMOS摄像头 其摄像头包含30w像素的CMOS图像感光芯片 3 6mm焦距的镜头和镜头座 板载CMOS芯片所需要的各种不同电源 电源要求详见芯片的数据文件 板子同时引出控制管脚和数据管脚 方便
  • 版本号比较 [java]

    原文地址 java版本号比较 思路 将版本号按点分割 并转成数字类型 放入list 取两个版本位数的最大数 如 1 0 1为3位 1 0 0 1为4位 将位数不够的版本进行补全 不够部分补成0 从第一位开始比较 出现大于情况返回1 出现小于
  • 为什么米聊干不过微信

    1 核心功能不稳定 2 广播太多用户体验差 3 取名太局限 4 发展新朋友能力有限 5 运营能力差
  • C++set容器set和multiset区别

    C set容器set和multiset区别 学习目标 掌握set和multiset的区别 区别 set不可以插入重复数据 而multiset可以 set插入数据的同时会返回插入结果 表示插入是否成功 multiset不会检测数据 因此可以插
  • QT 自定义信号和槽

    好久没有静下心来思考了 每天靠工作驱动 忙碌但不踏实 QT信号与槽机制一直在用 也会用 但只是知其然不知其所以然 今天临近下班给自己点清醒的时间 详细了解了下 总结如下 信号与槽机制是QT中不同对象相互通信的一种方法 有两种写法 第一种是S
  • Cassandra创建键空间(Keyspace)

    Cassandra查询语言 CQL 可帮助开发人员与Cassandra沟通交互 Cassandra查询语言的语法与SQL非常相似 什么是键空间 Keyspace 键空间 Keyspace 是用于保存列族 用户定义类型的对象 键空间 Keys
  • ios 超签签名服务器搭建(超签)

    为什么要搭建签名服务器吗 因为应用不能上架App Store 使用企业签名频繁掉签造成客户流失 用户体验不好 ios安装的app有几种方式吗 1 App Store 安装 符合法律法规的能走app Store的app 2 企业签名安装 灰色
  • Paxos算法细节详解(一)--通过现实世界描述算法

    Paxos算法细节详解 一 通过现实世界描述算法 Paxos分析 最近研究paxos算法 看了许多相关的文章 概念还是很模糊 觉得还是没有掌握paxos算法的精髓 所以花了3天时间分析了libpaxos3的所有代码 此代码可以从https
  • SpringBoot_5

    SpringBoot对静态资源的映射规则 如果我们需用给web项目中添加css js html文件的话 我们会发现此时没有webapp目录 由于springboot是以jar包的方式打包程序的因此是没有webapp目录的 那么我们的css
  • VMware虚拟机从一台电脑复制到另一台电脑

    在一台电脑上利用虚拟机创建了centos 如果想在家里的电脑虚拟机上也运行centos 不用再重新安装以及漫长的安装等待了 可以利用先前在虚拟机上安装centos生成的 vmx文件和 vmdk文件 拷贝到U盘 再重新导入到新电脑就可以了 省
  • DBMS_STATS分析表 (zt) dbms_stats.set_table_stats 手工设置统计信息

    作用 DBMS STATS GATHER TABLE STATS统计表 列 索引的统计信息 DBMS STATS GATHER TABLE STATS的语法如下 DBMS STATS GATHER TABLE STATS ownname V
  • 关于React + Antd 按需引入样式未生效问题

    第一步 npm install antd 安装antd 第二步 在根目录下创建 babelrc文件 配置按需引入需要用到的plugin npm install save dev import babel import presets bab
  • 跨服务器共享文件,不同服务器之间实现文件共享

    不同服务器之间实现文件共享 内容精选 换一换 表1列出了弹性文件服务的常用功能 在使用弹性文件服务之前 建议您先通过常用概念介绍了解NFS CIFS等基本概念 以便更好地理解弹性文件服务提供的功能 表示该类型的文件系统支持该功能 表示该类型
  • 自定义指令的说明和注册

    自定义指令说明 Vue3 除了核心功能默认内置的指令 v model 和 v show Vue 也允许注册自定义指令 v xxx 注意 代码复用和抽象的主要形式是组件 然而 有的情况下 你仍然需要对普通 DOM 元素进行底层操作 这时候就会
  • Linux/多线程的同步与互斥

    线程安全 多个执行流对资源进行争抢访问 但不会产生数据二义性 线程安全的实现 同步 互斥 同步 通过条件判断实现对临界资源访问的合理性 互斥 通过同一时间对临界资源的唯一访问 实现对临界资源访问的安全性 互斥锁 互斥的实现 互斥锁 在多任务