<mutex>注释 11:重新思考与猜测、补充锁的睡眠与唤醒机制,结合 linux0.11 操作系统代码的辅助(上)

embedded/2024/12/22 0:08:59/

(46)问题的起源

在这里插入图片描述

++ 因为上面的内核代码,我们编写多线程代码时,对手里的家伙事不那么自信。但我们知道,多线程在竞争锁时,若得不到锁,会进入睡眠,并会在被唤醒后重新尝试得到锁,一直到得到了锁,线程才会继续执行下面的代码。这种线程的睡眠与唤醒机制。参考 linux 0.11 里的进程睡眠与唤醒机制。给出 linux 0.11 的源代码。

(47) 寻找 linux 0.11 的睡眠与唤醒代码

在这里插入图片描述

++ 如图,在硬盘的读写过程中,对应硬盘块的内存块,是不允许被修改的。会被加锁。或者说,所有等待该内存块的进程,都会失去 CPU,被标记为 TASK_uninterruptable 状态。 进程 PCB 的 地址存储在 buffer_head . b_wait 成员里。 最后由当前操作硬盘的进程依次唤醒所有等待的线程。

(48)下图是睡眠与唤醒的原理

在这里插入图片描述

(49)如下图,系统的内存缓冲区是有限的。可以接受的硬盘读写请求,也是有限的,最多 32 个,这时候,都会导致太多的进程请求去睡眠

在这里插入图片描述

(50)下图里介绍了 linux 0.11 设置的进程的几种状态。区别 task_interruptable 与 task_uninterruptable 。后者不可被随便唤醒,只等待的进程来唤醒。前者可以接受信号的唤醒,比如定时器信号的唤醒。

在这里插入图片描述

(51) 定时睡眠的唤醒的原理支持如下。该睡眠会在进程调度时,触发进程收到一个 定时器信号 : SIGALRM 。该处于 task_interruptable 状态的进程就会 恢复运行。

在这里插入图片描述

(52) 那么,进程会单纯因为时间而睡眠么? 会的,下面的函数,就说明,进程会睡眠的,让出 CPU ,设置 task_struct . alarm 成员:

在这里插入图片描述

++ 以及:

在这里插入图片描述

++ 在定时中断中会维护这个定时器值。(同时下图也说明了,在 int 80H 与定时中断里,进程会响应信号量,这已经相当频繁了。):

在这里插入图片描述

++ 函数 do_timer ( ) 的源码

在这里插入图片描述

++ 结合上图,再修正一下语言,不是在 do_timer()里完成进程的定时器逻辑。而是在 时间中断 _timer_interrrupt 里递增了全局量 jiffres

(53) 上面的分析,已经指出了 sleep() 睡眠,触发的信号量 SIGALRM 。那么进程如何进入 task_interruptable 状态呢?因为没有 sleep() 函数的源代码。但是知道 waitpid () 函数,也会使进程自身睡眠,并也进入 task_interruptable 状态

在这里插入图片描述

++ 以及 wait_pid()。该函数里有对进程状态的设置

在这里插入图片描述

(54) 以上关于定时睡眠的理论分析,基于 linux 0.11 。但也适用于,可以为现代的 C++ STL 库中的条件变量 conditon_variable 提供指导, cv 包含了关于时间的成员函数。举例如下::

在这里插入图片描述

++ 上图引用了模糊的内核函数 ,_Cnd_timedwait (…) ,因为没有其源代码,不清楚锁与定时睡眠引起的线程唤醒与睡眠的关系,才引出了本文的推导与求证,试图自圆其说,更接近一些真相。核心问题就是:线程没育抢到锁的时候,还会醒来么?加了定时睡眠呢?醒来后代码流程还会继续么? unique_lock 在析构时候,如何处理锁呢?

(55)通过以上的分析,得出的结论是** 定时睡眠,使进程进入了可中断睡眠状态。到时后会因为信号 SIGALRM 被唤醒,恢复进程的执行**。而在 linux 里,认为线程是轻量级的进程,这里试图类比线程为进程来理解线程。

(56)对于现代的 c++ STL 库里引起的代码逻辑,只可以用测试,来感觉里面的涉及操作系统的信号的,锁的,条件变量的代码逻辑。 先给出第一版,这是最正确的,最简单的一版,随后再修改和复杂其中的逻辑:

在这里插入图片描述

++ 以及:

在这里插入图片描述

++ 以及:

在这里插入图片描述

++ 以及:

在这里插入图片描述

++ 作为强烈对比:把上面的锁 mutex 换成 timed_mutex 就会得出完全不一样的结果,代码逻辑不变:

在这里插入图片描述

++ 正是为了解释此问题,引出了本篇文章与下一篇文章

(57) 补充 cv 的函数特性

在这里插入图片描述

(58) 这俩图还搬过来:

在这里插入图片描述

++ 以及:

在这里插入图片描述

(59)继续分析为什么定时 mutex 可以准确的依据时间。先给出一个图:

在这里插入图片描述

(60)

谢谢


http://www.ppmy.cn/embedded/147656.html

相关文章

金碟中间件-AAS-V10.0安装

金蝶中间件AAS-V10.0 AAS-V10.0安装 1.解压AAS-v10.0安装包 unzip AAS-V10.zip2.更新license.xml cd /root/ApusicAS/aas# 这里要将license复制到该路径 [rootvdb1 aas]# ls bin docs jmods lib modules templates config domains …

前端解析超图的iserver xml

前端解析超图的iserver xml const res await axios.get(url)const xmlDom new DOMParser().parseFromString(res.data, text/xml);// 获取versionconst version xmlDom.getElementsByTagNameNS(*, ServiceTypeVersion)[0].textContent// 获取layerconst layerDom xmlDom.ge…

发布/部署WebApi服务器(IIS+.NET8+ASP.NETCore)

CS软件授权注册系统-发布/部署WebApi服务器(IIS.NET8ASP.NETCore) 目录 本文摘要VS2022配置发布VS2022发布WebApiIIS服务器部署WebApi 将程序文件复制到云服务器添加网站配置应用程序池配置dns域名配置端口阿里云ECS服务器配置19980端口配置https协议 (申请ssl证书)测试WebAp…

遥感影像目标检测:从CNN(Faster-RCNN)到Transformer(DETR

我国高分辨率对地观测系统重大专项已全面启动,高空间、高光谱、高时间分辨率和宽地面覆盖于一体的全球天空地一体化立体对地观测网逐步形成,将成为保障国家安全的基础性和战略性资源。未来10年全球每天获取的观测数据将超过10PB,遥感大数据时…

metagpt中ActionNode的用法

目录 整体流程1. 基础组件:2. SIMPLE_THINK_NODE 和 SIMPLE_CHECK_NODE:3. THINK_NODES 类:4. ThinkAction 类:5. SimplePrint 类:6. Printer 类:7. main 函数:总结:主要执行流程&am…

腾讯云全方位安全防护!

在流量暴增的数字时代,电商大促、在线直播、金融交易等场景下,业务暴涨固然可喜,但随之而来的系统压力和网络攻击也让人寝食难安。系统崩溃、访问卡顿、数据泄露……这些问题不仅影响用户体验,更可能让你失去市场和客户的信任。 …

面试题整理11----简述Pod创建过程

面试题整理11----简述Pod创建过程 1. 提交Pod定义2. API Server处理请求3. 调度器选择节点4. 绑定Pod至Node5. Kubelet执行6. Pod就绪和运行 在Kubernetes中,Pod的创建过程涉及多个组件的协同工作,确保Pod能够高效、稳定地运行。以下是Pod创建过程的详细…

GaussDB 企业版轻量化部署探索(二)

华为高斯数据库(GaussDB)是目前国产数据库中综合实力比较靠前的数据库之一。高斯数据库有单机开源版openGauss和企业版(包括集中式和分布式)。本文接上文《GaussDB 企业版轻量化部署探索》继续分享如何使用TPOPS在小规格内存服务器…