中断、信号、锁、信号量

1. 碎碎念

作为一个上学能忘记带书包,出门能忘记带钥匙的人。兴冲冲的去看书,发现自己木有带书,只带了电脑,好像也就没什么可奇怪的了。好在现在是 2019 年,在网上找了下要看书的 pdf 版,完美解决小插曲,撒花。(ps 解释下,作为一个尊重知识产权的人,我还是买了纸质书的哈

2. 背景

对于中断、信号、锁、信号量这几个操作系统课本里常见的概念,笔者始终是木有理解清楚过。大概率是因为我上学的时候没有好好听过课,不过也有可能是老师压根就没有讲过(ps 老师说这个锅我不背。作为一个健忘的「好奇宝宝」,笔者决定总结下这几个常用的概念,为了能够深刻的理解,将按照以下的步骤逐个概念分析:

  • why — 为什么需要 XX ?
  • what — XX 是什么 ?
  • how — XX 怎么做?

3. 中断

「任何操作系统内核的核心任务,都包含有对连接到计算机上的硬件设备进行有效管理。」翻译一下,硬件设备指硬盘、键盘、鼠标等,管理指的是通信。那么问题转化为处理器如何跟硬件设备间通信,能够枚举的通信方式有:

  • 一问一答的模式,即处理器向硬件发送一个请求,然后傻傻的等着硬件的回答
  • 处理器主动的模式,即处理器向硬件发送一个请求后,转去做其他的工作,同时定期轮询硬件完成的进度
  • 硬件主动模式,即处理机器向硬件发送一个请求后,转去做其他的工作,硬件在工作完成时主动通知处理器

注意: 处理器的速度跟硬件设备(外围设备)的速度往往不是一个数量级的,为了能够充分利用处理器,显而易见,第三种策略有着绝对的优势。

在这里插入图片描述

3.1 为什么需要中断

中断能够提高计算机的工作效率、增强计算机功能。引入中断的主要原因,是出于性能的考虑。上图的第三种即中断,反复轮询的方式会引起大量处理器周期被浪费。

3.2 中断是什么

在解释中断是什么之前,让我们先对中断做个分类,这两个分类大家应该都听的耳朵都快起茧子了,但是详细问区别的话……,反正我是说不清楚:

  • 硬件中断

    硬件中断是一种电信号,由硬件设备生成,直接送入中断控制器,当接收到一个中断后,中断控制器会给处理器发送一个电信号。处理器中断当前工作转去处理中断。

    中断控制器是个简单的电子芯片,作用是将多路中断管线,采用复用技术只通过一个和处理器相连的管线与处理器通信。

    ps 我觉得这个表达的应该是 N -> 1 -> 1 的一个过程,即 N 种中断转发给中断处理器,然后中断处理器再转发给处理器

  • 软件中断

    软中断是一组静态定义的下半部接口,可以在所有的处理器上同时执行,即使两个类型相同的也可以。但一个软中断不会抢占另外一个软件中断,唯一可以抢占软件中断的是硬中断。

    ps 我觉得这个想表达的应该是软件中断本质是内核预先定义的一些接口,当触发的时候,会中断当前的流程转去执行接口的内容

软中断和硬中断的区别是什么?(ps 此处摘自网络,笔者思考过,感觉他写的木有什么错的,但是就是教课书的内容,比较枯燥

  • 产生:软中断是执行中断指令产生的,而硬中断是由外设引起的

  • 中断号:硬中断的中断号由中断控制器提供,软中断的中断号由指令直接指出

  • 屏蔽:硬中断可屏蔽,软中断不可屏蔽

    硬件中断和软件中断执行的时候都需要通过中断向量表找到中断触发后待执行的指令。硬件中断需要通过中断控制器翻译一次,可以屏蔽,但是软件中断直接提供中断号,所以没有办法屏蔽。笔者是这么猜测的,未必正确。

3.3 中断怎么做

在理解中断做了什么之前,让我们先思考下中断的限制。

  • 中断是以异步的方式执行的,会打断其他代码的执行顺序,所以要求中断执行的越快越好。

  • 中断执行过程中有可能屏蔽其他类型的中断,禁止中断后硬件于操作系统无法通信,导致系统长时间无法响应。

  • 中断处理程序需要对硬件进行置位操作,所以有非常高的时限要求。

  • 中断在中断上下文中执行,中断上下文中找不到关联的进程,所以中断上下文不可以睡眠,也不可以调用睡眠的函数。

    进程以进程上下文的形式连接到内核中,能够找到关联的进程,可以重新被调度,进程上下文可以睡眠

结论:操作系统必须有一个能快速、异步、简单的机制负责对硬件做出迅速响应并完成那些对时间要求很严格的操作。

问题:中断能过做到异步、简单,但是还没有办法做到快速,所以中断怎么做的呢?

又中断处理程序运行得快,又想中断处理程序完成的工作量多(ps 又想马儿跑的快,又不想马儿吃草,马儿好难啊。所以此处实际使用的时候,把中断分为上下两部。

上半部:接收到一个中断,它就立即开始执行,但是只做严格的时限的工作,比如对接收的中断进行应答和复位硬件。

下半部:执行与中断处理密切相关但中断处理程序本身不执行的工作。

概念总是很难理解啊……

比如硬件数据收满,或者超时,触发中断,下半部负责解析、接收数据,上半部负责把数据拉走

其实就是中断处理流程如果太长的话,会干扰到正常的执行流程,索引这里拆分出上下部的概念。上半部,必须立刻处理,下半部不急,可以慢慢处理

思考个问题:软件中断所经过的流程比硬件中断要少嘛?

答案:是的,软件中断,进程 -> 内核中的设备驱动程序,硬件中断,硬件 -> CPU -> 内核中的设备驱动程序。软件中断比硬件中断少了一个硬件发送信号的 步骤,产生软件中断的进程一定是当前运行的进程,因此它们不会中断 CPU,但是它们会中断调用代码的流程。

4. 信号、锁、信号量

4.1 信号

软中断是一种机制,信号是软中断机制的一种体现,所以在使用信号过程中,我们能够中断代码的调用流程。此外,软中断还被用于系统调用中。

4.2 锁 vs 信号量

我之前写一篇关于锁的文章的时候,我就一直在思考锁、信号量到底代表了什么。不过很惭愧的是,写完了问题也木有想清楚,直到最近看到文章里写「为了保护数据而不是代码」,感觉突然间就想清楚了。

锁、信号量的本质就是一个变量,是锁还是信号量无非是理解上的问题,是人们赋予它逻辑上的意义。

比如锁,

  • 该变量初始值为 1,未加锁转态
  • 线程 A 将该变量值减 1,加锁转态,继续运行
  • 线程 B 将该变量值继续减 1,值为 -1,不满足可加锁状态,线程 B 会阻塞在这里(ps 此处线程处于阻塞态
  • 线程 A 将该变量值加 1,解锁状态,继续运行
  • 线程 B 获取锁,等待被调度(ps 此处线程处于就绪态
  • 线程 B 被调度,运行 (ps 此处线程处于运行态

进程、线程模型的就绪、阻塞、运行态也顺便理解了一波

信号跟锁类似,只不过初始值的大小可以大于 1

锁是共享资源访问的一种同步手段,为什么锁能够做到呢?

因为很多共享资源在修改和访问的时候都会涉及到很多个原子操作,很多的进程或者线程访问多个原子操作的时候顺序会不确定,所以为了保护多个原子操作,能够按照预期结果输出,人们提出了锁。

笔者思考了一个例子,假设你有一个三间大房子,你想保护你的房子不被坏人偷盗,最简单的做法是什么,圈一个院子出来,然后加上一个门,这样你只要保护你的门就可以了。

此处,三间房子就是多个原子操作

此处,围上院子 + 门就是锁

就写到这里吧,木有理解的深入,碎碎念的记录一下,防止自己以后忘记,还有我好想去看柯南啊……

5. 参考资料

Guess you like

Origin blog.csdn.net/phantom_111/article/details/100861821