用户进程不可以直接操作系统资源,因为如果给予进程的权利过大,可能会出现一些非法的访问,导致系统处于不安全的状态。基于这种原因,将系统所处状态分为用户态和内核态:
用户态:CPU 只能受限的访问内存,并且不允许访问敏感的系统资源,如:I/O 设备
内核态:CPU 可以访问任意数据,包括系统资源,还可以决定切换进程
当一个用户进程需要访问硬件资源时,需要进行系统调用,让操作系统去访问硬件资源,然后将结果返回给用户进程。系统调用相当于内核提供给用户的一套 API,通过 API 可以间接完成对硬件的访问
在系统启动时内核会设置好陷阱表,该表中存放了陷阱类型和内核代码位置的对应关系,也就是如果执行到陷阱 A,就会去执行陷阱 A 对应的内核代码
当用户线程系统调用时,会执行特殊的陷阱指令,该指令会从用户态转化到内核态,进而去执行该陷阱对应的内核代码。当操作系统执行完对应代码后,会从内核态转化到用户态
操作系统也算是一种软件,在单核 CPU 中,如果用户进程在 CPU 上执行,那么操作系统是无法执行滴,只有当用户态转化到内核态,操作系统才可以在 CPU 上执行。所以系统调用不仅从用户态转化到内核态,而且还相当于进行了一次上下文切换,从用户进程切换到操作系统进程
下面是通过系统调用完成上下文切换的过程:
对系统资源的访问、上下文切换等操作都需要操作系统来执行。系统调用可以从用户态切换到内核态,让控制权重新回到操作系统手中,但如果一个进程始终都不进行系统调用呢?那就会出现一直不能切换到内核态,从而卡死的情况
为了避免这种情况的发生,提出了时钟中断。时钟设备可以每隔几毫秒就生成一次中断,中断产生时,当前正在运行的程序停止,操作系统中预先配置的中断程序会运行,此时操作系统重新获得了 CPU 的控制权
下面是通过时钟中断完成上下文切换的过程:
在处理中断时,中断处理程序会将中断关闭,如果处理时间过长,可能会丢失其它设备的中断信号。为了避免丢失中断信号,将原来的整个中断过程分为两部分:
第一部分:快速处理中断,该阶段会暂时关闭中断,但一般该阶段耗时较短,只会处理与硬件相关敏感的事情
第二部分:交由操作系统完成中断剩余工作,该阶段会将中断打开,不会丢失中断信号
可以将第一部分看作是硬中断,也就是会关闭中断的中断;可以将第二部分看作是软中断,也就是不会关闭中断的中断。软中断可以大大降低中断信号丢失的风险
操作系统导论