前言
本文深度为上层语言(Java、go等)后端实习生面试难度,力求简洁明了。
一、什么是用户态?什么是内核态?
操作系统为了保护自己,严格控制用户程序的资源访问。不需要外部资源的程序运行状态是用户态,反之如果需要内核帮忙操作资源,此时就是内核态。
内核态下,CPU可以访问内存所有数据, 包括外围设备, 例如硬盘, 网卡. CPU也可以将自己从一个程序切换到另一个程序;
用户态下,只能受限的访问内存, 且不允许访问外围设备。占用CPU的能力被剥夺, CPU资源可以被其他程序获取。
二、为什么需要划分用户态和内核态
主要是为了安全。
在CPU指令中,有些指令是非常危险的,如果错用将导致系统崩溃,比如清内存、设置时钟等,所以CPU将指令分为特权指令和非特权指令。对于危险指令,只允许操作系统及其相关模块使用,普通应用程序只能使用不危险的指令。
三、用户态和内核态之间的切换
用户态 --> 内核态 的三种情况:
1、系统调用
系统调用的本质其实也是中断,相对于外围设备的硬中断,这种中断称为软中断。这是用户态进程主动要求切换到内核态的一种方式。用户态进程通过系统调用申请使用操作系统提供的服务程序完成工作。
例如:fork()就是执行了一个创建新进程的系统调用
2、异常
当cpu在执行运行在用户态下的程序时,发生了一些没有预知的异常,这时会触发由当前运行进程切换到处理此异常的内核相关进程中,也就是切换到了内核态。
例如:缺页异常
3、外围设备的中断
当外围设备完成用户请求的操作后,会向CPU发出相应的中断信号,这时CPU会暂停执行下一条即将要执行的指令而转到与中断信号对应的处理程序去执行,如果前面执行的指令时用户态下的程序,那么转换的过程自然就会是 由用户态到内核态的切换。
例如:硬盘读写操作完成,系统会切换到硬盘读写的中断处理程序中执行后边的操作等。
操作完成后,会从内核态退回用户态。
参考:【linux】10分钟搞懂用户态与内核态_哔哩哔哩_bilibili