当前位置: 首页 > news >正文

Linux wait_on_buffer函数研究

Linux0.11内核中的wait_on_buffer和wait_on_inode函数是非常有代表性的延迟性函数处理过程,网上关于这两个函数的讨论

也很多,最主要的一个问题是为什么要在判断b_lock之前关中断,这个问题也困扰了我很长时间,查了不少帖子,学到不少东西,但总是

觉得有些细节没有弄清楚,因此借着自己实践开发一个小OS的过程,研究了一下wait_on_buffer,还是学到不少东西的。贴出来,分享

给大家,欢迎讨论~

Linux0.11版函数定义:

static inline void wait_on_buffer(struct buffer_head * bh)
{
cli();
while (bh->b_lock)
sleep_on(&bh->b_wait);
sti();
}

分析如下:

1. 首先可以明确,wait_on_buffer是工作在内核态的函数。更进一步应当理解为两种可能性:

或者是当前某个用户态的进程请求数据进而引发的,那么可以认为是当前进程进入了内核态;又或者是内核本身的某个任务

引发的操作。不管怎样wait_on_buffer背后是代表这某个进程或者任务的。

2. wait_on_buffer中通过cli和sti起到一个保护临界区的作用,为什么这么说?

原因首先还在于wait_on_buffer是工作在内核态的环境下,此时cli就意味着关闭了所有的可屏蔽中断,如时钟中断和硬盘

处理中断等等,这也就意味着:

1)当前工作在用户态的进程不会因为时间片到了有可能被轮转出去,切换成其他的进程,从而保证while(bh->b_lock)形成的

若干条指令中间不会被打断,造成可能有别的进程修改了bh->b_lock的值,造成错误;

2)不会造成硬盘中断的到来引发的其他进程对bh->b_lock的操作,进而造成错误。

因此,通过关闭中断,可以达到while (bh->b_lock)语句在执行期间被他人修改,从而实现临界区的效果。

关于这一点,第3版的《Understanding the Linux Kernel》在第五章(内核同步)里明确也提到,确保一组内核语句被当作

一个临界区处理的主要机制之一就是中断禁止,可惜本人在上学时学的OS教材是理论性较强的那种,只关注了各种各样的临界操

作模型,没有提到实现机制,导致很长时间都觉得临界区的概念很虚,不好掌握。

3.还有一个重要的问题就是如果关闭了中断,那别的用户进程怎么办?是不是整个系统在这段时间内都不能收到相关的中断信号

了?这个问题也有很多人问,答案当然是不会影响其他的用户进程,原因在于sleep_on在将当前进程挂起后,会执行一次进程调

度操作,即schedule(),而一旦选择了新进程进行切换时,会将新进程的EFLAGS寄存器内容也加载到相应的寄存器的,而这里当

然包含了IF(Interrupt Flag)位,也就是说如果此时切换过来的进程是使用自己原先的中断开关状态的,原来的开就开,原来的关

就关,和之前的进程无关。因此,wait_on_buffer里对中断的操作,只影响当时的进程,故这个中断也被称为“本地中断”,这

个称呼更能反映其实质吧。

相关文章:

  • POJ - 2796 Feel Good(经典单调栈)
  • 基于Linux0.11源代码的操作系统内核典型处理过程分析1
  • POJ - 3494 Largest Submatrix of All 1’s(单调栈+降维)
  • 在批处理文件中实现按日期命名的目录迁移
  • HDU - 6806 Equal Sentences(dp)
  • UltraWinGrid自适应列宽/行高
  • HDU - 6812 Kindergarten Physics(分块/规律)
  • UltraGrid 卡片模式列自适应宽度
  • 2020牛客暑期多校第七场 B - Mask Allocation(思维)
  • 编程修改BIN等二进制文件
  • 2020牛客暑期多校第七场 H - Dividing(整除分块)
  • 2020牛客暑期多校第八场 K - Kabaleo Lite(贪心)
  • 什么是程序员正确的职场心态?
  • 2020牛客暑期多校第八场 I - Interesting Computer Game(并查集+离散化)
  • [J2ME]url请求返回参数非法(java.lang.illegalArgument)
  • Java 网络编程(2):UDP 的使用
  • JavaScript服务器推送技术之 WebSocket
  • JavaScript中的对象个人分享
  • Java基本数据类型之Number
  • Js基础——数据类型之Null和Undefined
  • js数组之filter
  • Linux各目录及每个目录的详细介绍
  • Mysql优化
  • Netty 4.1 源代码学习:线程模型
  • React-redux的原理以及使用
  • Spring Cloud Alibaba迁移指南(一):一行代码从 Hystrix 迁移到 Sentinel
  • 安装python包到指定虚拟环境
  • 基于axios的vue插件,让http请求更简单
  • 技术胖1-4季视频复习— (看视频笔记)
  • 如何在 Tornado 中实现 Middleware
  • 数组大概知多少
  • elasticsearch-head插件安装
  • Linux权限管理(week1_day5)--技术流ken
  • 好程序员web前端教程分享CSS不同元素margin的计算 ...
  • 智能情侣枕Pillow Talk,倾听彼此的心跳
  • ​决定德拉瓦州地区版图的关键历史事件
  • #、%和$符号在OGNL表达式中经常出现
  • #162 (Div. 2)
  • #pragma预处理命令
  • #QT(智能家居界面-界面切换)
  • $.each()与$(selector).each()
  • (android 地图实战开发)3 在地图上显示当前位置和自定义银行位置
  • (LeetCode C++)盛最多水的容器
  • (附源码)spring boot车辆管理系统 毕业设计 031034
  • (更新)A股上市公司华证ESG评级得分稳健性校验ESG得分年均值中位数(2009-2023年.12)
  • (使用vite搭建vue3项目(vite + vue3 + vue router + pinia + element plus))
  • (转)【Hibernate总结系列】使用举例
  • (转)创业的注意事项
  • (转)创业家杂志:UCWEB天使第一步
  • (转)关于如何学好游戏3D引擎编程的一些经验
  • (转)微软牛津计划介绍——屌爆了的自然数据处理解决方案(人脸/语音识别,计算机视觉与语言理解)...
  • .net core 调用c dll_用C++生成一个简单的DLL文件VS2008
  • .NET Remoting学习笔记(三)信道
  • .NET框架设计—常被忽视的C#设计技巧
  • .sys文件乱码_python vscode输出乱码