进程的用户态和内核态

操作系统的核心是内核(kernel),它独立于普通的应用程序,可以访问受保护的内存空间,也有访问底层硬件设备的所有权限。有些 CPU 的指令是非常危险的,一旦用错可能导致系统崩溃。如果所有的程序都可以任意使用这些指令,那么系统崩溃的概率将大大增加。为了保证内核的安全,操作系统一般都禁止用户进程直接操作内核。具体的实现方式是将虚拟内存空间划分为两部分,一部分为内核空间,另一部分为用户空间。当进程运行在内核空间时就处于内核态,进程运行在用户空间时则处于用户态。

无论是进程还是线程,它们的上下文切换和"内核态、用户态"没有直接的关系。比如只要需要系统调用,即使不做任何切换,都需要进入内核态。举个例子:一个线程调用函数在屏幕上打印 hello world,就已经进入了内核态了,因为打印字符的功能是由内核程序提供的。总的来说,应用程序通常运行在用户态,遇到下列三种情况会切换到内核态:

系统调用:创建和调度线程、加锁解锁等等。
异常事件:发生不可知的异常时切换到内核态,以执行相关的异常事件。
设备中断:如果外围设备完成了用户请求,比如硬盘读写操作,就会给 CPU 发送中断信号。CPU 会转去处理中断事件,切换到内核态。
线程的代码在用户态运行,而调度是在内核态运行的。操作系统切换线程上下文的步骤如下所示:

1)保留用户态现场(上下文、寄存器、用户栈等)
2)复制用户态参数,用户栈切到内核栈,进入内核态
3)代码安全检查(内核不信任用户态代码)
4)执行内核态代码
5)复制内核态代码执行结果,回到用户态
6)恢复用户态现场(上下文、寄存器、用户栈等)

参考:https://www.cnblogs.com/xiaoyangjia/p/16640741.html

posted @ 2022-09-05 14:13  strive-sun  阅读(1500)  评论(0编辑  收藏  举报