记录实现操作系统互斥锁的一次思考

news2024/11/18 21:42:29

今天实现操作系统互斥锁的时候遇到一个有趣的问题。

场景

有两个进程分别名为 taskA,taskB,采取时间片轮转的方式交替运行——也即维护了一个 ready_queue,根据时钟中断来 FIFO 地调度任务。它们的任务是无限循环调用 sys_print() 来打印自己的名称。

我还设置了一个 mutex 互斥锁,它包含一个 0/1 互斥信号量:用于表示锁是否已经被取走,还有一个等待队列 waiting_queue:用于存放正在等待该锁的进程。

为了保证打印出来的字符不错乱,我为 sys_print() 函数设置一个 mutex 对象,我们暂且称之为 print_mutex。在调用 sys_print() 前执行 mutex_lock() 上锁,如果此时锁已经被取走,那么将当前任务加入 print_mutex 的 waiting_queue。调用 sys_print() 后执行 mutex_unlock() 解锁,如果 waiting_queue 中有任务,那么将 print_mutex 直接分配给其中的第一个任务,同时将该任务加入进程的就绪队列,否则将锁归还,由需要该锁的进程主动来取锁。

运行

想一想,这时候运行系统,屏幕上的输出形式是怎么样的呢?

容易想到一些情况:

一、交替连续输出,且无打印出错误,形如以下形式

taskA
taskA
taskA
taskB
taskB
taskB
taskA
taskA
taskA
... ...

二、交替连续输出,但在进程切换的瞬间,有打印错乱的可能,形如以下形式

taskA
taskA
tastaskB
taskB
taskB
ttaskA
taskA
taskA
... ...

三、严格交替输出,且无打印出错误,形如以下形式

taskA
taskB
taskA
taskB
taskA
taskB
... ...

四、严格交替输出,但在进程切换的瞬间,有打印错乱的可能,形如以下形式

tasktaskB
tataskB
taskA
tataskA
... ...

其实还有很多其他可能,碍于篇幅受限,不再列出。

输出

很容易想到,加了互斥锁 print_mutex 后,肯定不会出现打印错乱的情况,因此情况二和情况四首先排除,那么到底是情况一还是情况三呢?大家可以根据场景先思考一下。

好了,公布答案,最终形式其实既不是情况一也不是情况三,而是这样的:

taskA
taskA
taskA
taskA
taskA
taskB
taskA
taskB
... ...

也就是一个任务先连续输出,然后两个任务严格交替输出,如下图:

在这里插入图片描述

分析

假设先上时间片运行的是 taskA,那么在第一个时间片周期中, taskA 可以调用 sys_print() 函数若干次,当时间片发生切换的瞬间,taskA 会被挂起,然后重新加入到 ready_queue 尾部,等待下一次被分配 cpu。

这个任务的功能很简单,可以简化成以下形式:

void taskA(){
    while(true){
        metux_lock();   //关中断保证原子操作
        sys_print();
        mutex_unlock(); //关中断保证原子操作
    }
}

其中 mutex_lock() 和 mutex_unlock() 都关中断保证了不会有时钟中断发生, 所以在切换进程的时候,taskA 可能会

  1. 停留在 metux_lock() 之前、mutex_unlock() 之后
  2. 停留在 sys_print() 中

显然,由于sys_print() 需要与外围设备端口交互,包含的指令数也比较多,而情况1 包含的指令数极少,因此 taskA 此时绝大概率停留在 sys_print() 中,也就是 taskA 持有 print_mutex 互斥锁,并在 ready_queue 中等待执行,而这时候 taskB 虽然被分配了时间片,但在执行 mutex_lock() 的时候发现锁已被取走,只能进入 print_mutex 的 waiting_queue 等待。taskA 重新上cpu 运行,执行完上次执行一半的 sys_print() 之后,紧接着执行 mutex_unlock() 将锁分配给锁等待队列中的 taskB,下一轮循环时,taskA 执行 mutex_lock() 发生锁等待被挂起,循环往复,两者就严格交替打印了。

事实上,如果 taskA 在切换时间片的时候遇到的是情况 1,那么也可能出现两个进程交替连续打印的情况,但是这个概率极小。

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

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

相关文章

华为OD机试题,用 Java 解【用户调度问题】问题

华为Od必看系列 华为OD机试 全流程解析+经验分享,题型分享,防作弊指南)华为od机试,独家整理 已参加机试人员的实战技巧华为od 2023 | 什么是华为od,od 薪资待遇,od机试题清单华为OD机试真题大全,用 Python 解华为机试题 | 机试宝典使用说明 参加华为od机试,一定要注意不…

Java基础常识

目录 JDK和JRE和JVM分别是什么?有什么关系? 什么是字节码,采用字节码的好处是什么 ? Java 程序从源代码到运行的过程 为什么 Java语言"编译与解释并存" Java 和 C、Go 语言的区别,各自的优缺点? JDK和JRE和JVM分别是什么?有什么关系…

Flink相关介绍

简介 Flink的定位是:Apache Flink是一个框架和分布式处理引擎,如图所示,用于对无界和有界数据流进行有状态计算。Flink被设计在所有常见的集群环境运行,以内存执行速度和任意规模来执行计算。 Flink 框架处理流程应用场景 1、电…

程序员应该如何学习算法?

算法不是纯粹拼智商的,初学者不要上来直接撸《算法导论》!这是血泪 建议一:首先你得会一门程序设计语言 建议二:基础知识,数据结构,推荐大家看一下《大话数据结构》这本书,这本书看过感觉&…

华为OD机试用Python实现 -【连续字母长度 or 求第 K 长的字符串长度】 | 2023.Q1 A卷

华为OD机试题 本篇题目:连续字母长度 or 求第 K 长的字符串长度题目输入描述输出描述示例一输入输出说明示例二输入输出说明示例三输入输出说明Code代码编写逻辑最近更新的博客 华为od 2023 | 什么是华为od,od

zookeeper使用场景实战

ZK java客户端 zk官方客户端没有和服务端分离,同一个jar文件,我们直接引入zk的maven即可。注意版本匹配兼容 Curator curator java语言编程的zk客户端框架,curator项目是现在zk客户端中使用最多。 将我们平时使用的zk服务开发进行了封装&a…

【Linux】进程状态(阻塞、挂起、僵尸进程)

文章目录1 阻塞与挂起1.1 阻塞1.2 挂起2 进程状态前言: 当我们在Windows下双击运行一个程序,或是在Linux下通过 ./ 加载运行一个程序,是否就代表对应的进程就一直处在运行状态呢?其实不然,一个进程有许多不同的状态。当…

科技和女性的今天,《赛博格宣言》半个世纪前就预言了

近几年,我们团队在实地探访各行各业数字化时,格外关注女性工作者的存在,一个强烈感受是:和女性主义理论中说的一样,因为有了数字化技术,工作对于体力、精力等要求不再苛刻,岗位上的女员工就多了…

设计模式~门面(外观)模式(Facade)-08

目录 (1)优点 (2)缺点 (3)使用场景 (4)注意事项: (5)应用实例: (6)源码中的经典应用 代码 外观模式&am…

类和对象万字详解

目录 一、面向对象与面向过程的区别 面向过程: 面向对象: 二、类的引入 class与struct爱恨情仇 class的语法 类的定义: 类的限定访问符 类的实例化 类对象模型 this指针的应用 三、封装 四、类的六个默认成员函数 构造函数 再谈…

基于NMOSFET的电平转换电路设计

一、概述: 在单片机系统中,5V、3.3V是芯片常用的电平。而在传输协议中(如IIC、SPI等协议),存在芯片与芯片的高电平和低电平定义的范围不一样,所以需要存在一个电平转换电路,来使芯片与芯片之间顺利的传输。 二、前置…

JDK动态代理(tedu)(内含源代码)

JDK动态代理(tedu)(内含源代码) 源代码下载链接地址:https://download.csdn.net/download/weixin_46411355/87546187 目录JDK动态代理(tedu)(内含源代码)源代码下载链接…

vue2学习笔记

文章目录1. 初识Vue2. 模板语法3. 数据绑定4. el与data的两种写法5. Vue中的MVVM6. 数据代理Object.defineProperty方法何为数据代理Vue中的数据代理7. 事件处理事件的基本使用事件修饰符键盘事件8. 计算属性姓名案例_插值语法实现姓名案例_methods实现姓名案例_计算属性实现姓…

dp-过河卒

题目描述 如图,A 点有一个过河卒,需要走到目标 B 点。卒行走规则:可以向下、或者向右。同时在棋盘上的 C 点有一个对方的马,该马所在的点和所有跳跃一步可达的点称为对方马的控制点。 例如上图

【HashMap】| 深度剥析Java SE 源码合集Ⅱ | 你会吗?

目录一. 🦁 HashMap介绍1.1 特点1.2 底层实现二. 🦁 结构以及对应方法分析2.1 结构组成2.1.1 成员变量2.1.2 存储元素的节点类型2.1.2.1 链表Node类2.1.2.2 树节点类2.1.2.3 继承关系2.2 方法实现2.2.1 HashMap的数组初始化2.2.2 计算hash值2.2.3 添加元…

HTML URL

HTML 统一资源定位器 (Uniform Resource Locators) URL 是一个网页地址。 URL 可以由字母组成,如 "w3cschool.cn",或互联网协议(IP)地址: 120.79.88.157。大多数人进入网站使用网站域名来访问,因…

主流的“对象转换工具”使用示例大全以及性能的对比

目录 前言 源码地址 代码示例 引入依赖 先定两个实体用于转换 定义一个接口让所有转换器都集成 Apache BeanUtils BeanCopier bean-mapping bean-mapping-asm Dozer 自己写get/set JMapper json2json MapStruct(推荐) ModelMapper OriK…

使用Vue实现数据可视化大屏功能(二)

引入数据大屏相关组件 用Datav插件做大屏可视化的组件,官网地址 http://datav.jiaminghi.com/ ,整个组件库都是基于Vue React版本实现,主要用于构建大屏数据可视化页面,具有很多种类的组件可以使用。其安装方式如下。 npm instal…

WebRTC中的NAT穿透

NAT简介 我们知道,WebRTC会按照内网、P2P、中转的顺序来尝试连接。在大部分的情况下,实际是使用P2P或者中转的。这里P2P的场景主要使用的技术就是NAT穿透。 我们先简单了解下NAT。NAT在真实网络中是常见的,它的出现一是为了解决ipv4地址不够…

2.1操作系统-进程管理:进程的同步与互斥、信号量与PV操作、PV操作与互斥模型、PV操作与同步模型

2.1操作系统-进程管理:进程的同步与互斥、信号量与PV操作、PV操作与互斥模型、PV操作与同步模型进程的同步与互斥PV操作PV操作与互斥模型PV操作与同步模型进程的同步与互斥 进程是动态的,有一些动态变迁的过程,进程在计算机中是可以同时存在…