在下列事件中,进程可能把控制权交给操作系统:
- 系统调用:应用程序主动向操作系统发出的服务请求
- 异常:非法指令或者其他原因导致当前指令执行失败后的处理请求
- 中断:来自硬件设备的处理请求
1.为什么需要中断、异常和系统调用
在计算机系统中,内核是被信任的第三方,可以在里面做对计算机系统里的任何内容的控制,而且可以执行它的特权指令。这种信任并不是指内核和外界隔离,它还需要为上面的应用程序提供服务。也就是说它必须对外界提供某种访问的接口或者打交道的通道。
2. 中断和异常解决的问题
- 解决当外设与系统有交互时的处理问题
- 应用程序执行碰到意外时,由异常来处理
3. 系统调用希望解决的问题
- 解决应用程序既能方便的调用系统服务,又不至于用户的行为影响内核的安全。
4. 内核的进入和退出
操作系统和外界打交道基本就是通过中断、异常、和系统调用这三个接口
内核的进入和退出共有3种情况
情况1:和外界硬件打交道
在键盘敲入了一定数据后,必须通过中断通知内核,内核通知驱动来实现与设备进行数据交互。
情况2:代码执行出错
比如说存储访问指令访问到某一个存储单元,但这个单元并不允许访问,这时候就需要异常处理机制,把控制权交给内核。
情况3:正常情况下
应用程序会使用函数库,这时候和内核不打交道。但是内核、函数库、应用程序会间接的通过系统调用接口使用操作系统内核的服务。比如说应用程序需要读写数据到外部设备,应用程序通过系统调用接口所提供的函数进入内核,内核把相应的数据读出来返回给应用程序
从上图我们可以看出系统内核是如何与外部设备和应用程序打交道的,这也是操作系统的主要功能:基于硬件设备之运行,为上层的应用程序提供系统服务。
(一)从宏观上把握关键部分
在宏观上主要是包括三个部分的内容:
第一个是操作系统内核,是整个内容的核心;
第二个是外部设备,包括了输入输出设备,存储设备等。
第三个是应用程序,主要是由用户运用的程序。
(二)处理过程:主要是讨论OS和外部设备以及应用程序之间的关系
1、操作系统与外部设备之间:主要通过中断机制来实现。
例如,在键盘在输出的时候,首先会把数据写到一个特定的缓冲区,这个缓冲区是有大小限制,如果数据超过其限制大小,先前数入的内容就会被冲掉,所以外部设备会通过中断机制,向内核发出指令,然后内核通过调用设备驱动程序,及时把缓冲区的内容读写到内核中。这样就达成了一个操作系统内核与外部设备进行数据交互的过程。
2、操作系统与上层应用程序:主要通过异常与系统调用两个机制来实现。
这里面可以分为两种情况来讨论,一种是应用程序异常运行程序的情况,另一种是应用程序正常运行的情况。
(1)异常的处理机制:例如在应用程序有一个程序片段,是一个除以零的代码,这显然是不合法的。在内核处理过程中,就会通过“异常服务例程"进行处理,捕获到异常的代码,然后抛出异常来即时处理,并返回异常处理结果。
(2)程序正常处理机制:这种情况是出现最多。当程序运行时,调用相关的函数库来获取系统调用接口,通过相关接口向存储设备或输入输出设备请求数据,然后在内核中处理应用程序,最后并把结果输出给用户或保存回存储设备。这个过程主要是依靠系统调用机制来实现。举个例子,银行储存着用户的钱,但是在用户取钱的时候,又不允许用户直接拿钥匙去开保险柜,所以需要对外提供一个服务的窗口。当用户需要拿钱的时候,就需要到柜台办理取钱业务,然后由柜台人员把钱取出来交给用户,此时的柜台人员就相当于系统调用接口,充当两者交流中心或处理中心的的中介作用。
一个故事:小明在看书,突然来了个电话,接完电话继续看书,这是中断;小明在看书,感觉口渴了,喝了水接着看书,这是异常。
类别 | 原因 | 同步/异步 | 返回行为 | |
中断 | 中断(interrupt) | 来自I/O设备或其他硬件部件 | 异步 | 总是返回到下一条指令 |
异常 | 陷入(trap) |
有意识安排的 | 同步 | 返回到下一条指令 |
故障(fault) | 可恢复的错误 | 同步 | 返回到当前指令 | |
终止(abort) | 不可恢复的错误 | 同步 | 不会返回 |
虽然系统调用比函数调用安全,但是系统调用比函数调用多了很多开销(主要是在内核态和用户态的切换上),一是切换的引导机制,二是第一次调用时会建立内核堆栈,三是验证参数。