《计算机操作系统-第三章》之中断与系统调用

前言

在你立足处深挖下去,就会有泉水涌出!别管蒙昧者们叫嚷:“下边永远是地狱!”

博客主页:KC老衲爱尼姑的博客主页 博主的github,平常所写代码皆在于此 共勉:talk is cheap, show me the code 作者是爪哇岛的新手,水平很有限,如果发现错误,一定要及时告知作者哦!感谢感谢!

1.中断机制的诞生

早期的计算机虽然对程序的处理是成批进行的,但是内存中始终只能处理一个程序,而CPU的处理速度是非常的快的,当CPU运行期间向IO设备发送输入或者输出请求时,高度运转的CPU需要等待龟速的IO完成状态。为了提高资源利用率,人们就发明了操作系统,引入了中断机制,实现了多道程序技术。

1.1什么是中断?

有了多道程序技术后,在内存就可以运行多个程序,CPU也能并发的执行多个程序。举个例子,先在有三个程序分别为A,B,C,当这三个程序加载到内存中后,程序A首先被处于用户态的CPU所处理,当计时部件检测到进程A的时间片消耗完之后,CPU会收到计时部件发出的中断信号,此时CPU会切换到核心态,而后操作系统的内核会对中断进行处理,具体就是操作系统会让CPU去处理程序B或者C,因为程序A的时间片已用完,当操作系统完成中断的处理后又会把CPU的使用权交给用户进程,即切换成用户态.这个时候进程B就会在用户态下开始工作,然后当进程B执行了一断时候后它可能会发出系统调用(内中断信号),请求输出,而输入输出的指令属于特权指令,因此CPU又切换为核心态对中断进行处理,它会向打印机发出命令让其开始工作去打印进程B的Hello World,此时进程B暂停运行,等待IO完成,核心态又会切换为用户态让进程C开始运行,并且打印机在操作系统的要求下会并行的工作,打印机工作完成后会发送IO完成的信号,操作系统收到后,又会介入让进程B恢复运行,已完成后续工作。

综上所述,中断是一个过程。当CPU在处理某个事件时,内部或者外部发生的某一事件请求CPU迅速去处理,于是CPU会暂停当前的工作,转而去处理发生的事件,处理完后再返回原来被终止的地方继续工作,这个过程称为中断。

1.2中断的特点
  1. 当中断发生时,CPU立即进入核心态
  2. 当中断发生后,当前运行的进程暂停运行,并由操作系统内核对中断进行处理
  3. 对于不同的中断信号,会进行不同的处理。

中断 的本质:让操作系统介入,进行管理。

用户态,核心态之间的切换是如何实现的?

用户态—>核心态是通过中断实现的。并且中断是唯一的途径。核心态—>用户态的切换是通过执行一个特权指令,将程序状态字的标志设置为用户态即可。

1.3中断的分类
1.3.1内中断

内中断也被称为异常,例外,异常

内中断信号的来源:来自CPU内部与当前执行的指令有关。

1.3.2外中断

外中断又分别为人工干预,外部请求

外中断信号来源:来自CPU外部与当前执行的指令无关。

外中断的处理过程

不同计算机的中断(指外中断)处理过程各具特色,就其多数而论,中断处理流程如图所示。

在这里插入图片描述

各阶段处理流程的描述如下:

  1. 关中断。CPU响应中断后,首先要保护程序 的现场状杰,在保护现场的过程中,CPU不应响应更高级中断源的中断请求。否则,若现场保存不完整,在中断服务程序结束后,也就不能正确地恢复并继续执行现行程序。
  2. 保存断点。为保证中断服务程序执行完毕后能正确地返回到原来的程序,必须将原来的程序的断点(即程序计数器PC)保存起来。
  3. 引出中断服务程序。其实质是取出中断服务程序的入口地址送入程序计数器PC
  4. 保存现场和屏蔽字。进入中断服务程序后,首先要保存现场,现场信息一般是指程序状态字寄存器PSWR和某些通用寄存器的内容。
  5. 开中断。允许更高级中断请求得到响应。
  6. 执行中断服务程序。这是中断请求的目的
  7. 关中断。保证在恢复现场和屏蔽字时不被中断。
  8. 恢复现场和屏蔽字。将现场和屏蔽字恢复到原来的状态。
  9. 开中断、中断返回。中断服务程序的最后一冬指会通觉是一冬中断返同指令,使其返回到原程序的断点处,以便继续执行原程序。

2.系统调用

2.1什么是系统调用?

系统调用时是操作系统给应用程序使用的接口,也就是说是供应用程序调用的特殊函数,应用程序可以发出系统调用请求来获得操作系统的服务。

2.2为什么需要系统调用?

举个栗子,张三去学校打印店打印学习资料,当你的那份学习资料打印到一半时,李四又使用打印机打印他的学习资料去了,而结果确是你和李四的学习资料都完美的打印出来并没有混杂在一起,都是按顺序打印出来的。假如这2个打印线程可以随意的使用,那么结果就是你和李四的学习资料会混杂在一起。而之所以没有混杂就是因为打印机的程序通过系统调用请求操作系统的服务,操作系统各个请求进行协调管理。

2.2.1作用

应用程序通过系统调用请求操作系统的服务。系统中的各种共享资源都由操作系统统一管理,因此在用户程序中凡是与资源相关的操作(文件管理,I/O操作),都必须通过系统调用的方式向操作系统提出服务请求,由操作系统代为完成。这样可以保证系统的稳定性和安全性,防止用户把计算机玩坏。

2.2.2系统调用的分类

按功能分类

  • 设备管理。完成设备的请求或释放,以及设备启动等功能。
  • 文件管理。完成文件的读、写、创建及删除等功能。
  • 进程控制。完成进程的创建、撤销、阻塞及唤醒等功能。
  • 进程通信。完成进程之间的消息传递或信号传递等功能。
  • 内存管理。完成内存的分配、回收以及获取作业占用内存区大小及始址等功能。

显然,系统调用相关功能涉及系统资源管理、进程管理之类的操作,对整个系统的影响非常大,因此必定需要使用某些特权指令才能完成,所以系统调用的处理需要由操作系统内核程序负责完成,要运行在核心态

2.3库函数与系统调用的区别?

首先应用程序是可以进行系统调用,前提是该程序是由汇编语言或者机器语言写的,但是现在的程序基本上都是高级语言 写的,高级语言为了是程序更加方便的进行系统调用会将操作系统的系统调用的函数再进行封装。所以高级语言中的部分库函数其实就是对系统调用的封装,另一部分库函数仅仅是完成某个功能而已,如单纯的求某个数的绝对值。而像文件的创建,读写则是会涉及系统调用。

2.4系统调用背后的过程

举个栗子,使用C语言打印Hello World,当我们运行所写的应用程序时,会触发系统调用write(),首会给系统调用函数传递参数,参数传递完后就会执行陷入指令(用户态),使得CPU切换到核心态去调用IO以及显示屏,当程序执行完了,再返回用户态。

注意:

  1. 陷入指令是在用户态执行的,执行陷入指令之后会立刻引发一个内中断,从而CPU进入核心态
  2. 发出系统调用请求是在用户态,处理请求是在核心态
  3. 陷入指令是唯一一个能在用户态下执行而不可在核心态下执行的指令。