进程上下文切换
用户态、内核态
-
内核态:也叫内核空间,是内核进程/线程所在的区域。主要负责运行系统、硬件交互。
-
用户态:也叫用户空间,是用户进程/线程所在的区域。主要用于执行用户程序。
内核态与用户态的区别
内核态与用户态是操作系统的两种运行级别,当程序运行在3级特权级上时,就可以称之为运行在用户态。因为这是最低特权级,是普通的用户进程运行的特权级,大部分用户直接面对的程序都是运行在用户态;
当程序运行在0级特权级上时,就可以称之为运行在内核态。
运行在用户态下的程序不能直接访问操作系统内核数据结构和程序。当我们在系统中执行一个程序时,大部分时间是运行在用户态下的,在其需要操作系统帮助完成某些它没有权力和能力完成的工作时就会切换到内核态(比如操作硬件)。
为什么要区分内核态和用户态
保护机制。防止用户进程误操作或者是恶意破坏系统。内核态类似于C++的私有成员,只能在类内访问,用户态类似于公有成员,可以随意访问。
这两种状态的主要差别是
处于用户态执行时,进程所能访问的内存空间和对象受到限制,其所处于占有的处理器是可被抢占的
处于内核态执行时,则能访问所有的内存空间和对象,且所占有的处理器是不允许被抢占的。CPU状态之间的转换
-
用户态—>内核态:唯一途径是通过中断、异常、陷入机制(访管指令)
-
内核态—>用户态:设置程序状态字PSW
通常来说,以下三种情况会导致用户态到内核态的切换
1、系统调用(主动)
这是用户态进程主动要求切换到内核态的一种方式,用户态进程通过系统调用申请使用操作系统提供的服务程序完成工作。比如前例中fork()实际上就是执行了一个创建新进程的系统调用。
由于用户态无法完成某些任务,用户态会请求切换到内核态,内核态通过为用户专门开放的中断完成切换。
而系统调用的机制其核心还是使用了操作系统为用户特别开放的一个中断来实现,例如Linux的int 80h中断。
用户程序通常调用库函数,由库函数再调用系统调用,因此有的库函数会使用户程序进入内核态(只要库函数中某处调用了系统调用),有的则不会。
2、异常(被动)
当CPU在执行运行在用户态下的程序时,发生了某些事先不可知的异常,这时会触发由当前运行进程切换到处理此异常的内核相关程序中,也就转到了内核态,比如缺页异常。
3、外围设备的中断(被动)
当外围设备完成用户请求的操作后,会向CPU发出相应的中断信号,这时CPU会暂停执行下一条即将要执行的指令转而去执行与中断信号对应的处理程序,
如果先前执行的指令是用户态下的程序,那么这个转换的过程自然也就发生了由用户态到内核态的切换。比如硬盘读写操作完成,系统会切换到 硬盘读写的中断处理程序 中执行后续操作等。