用户态和内核态:
是两种操作系统的运行级别,3级特权级别是用户态,0级特权级别是内核态。
一般程序员自己写的代码都是运行在用户态的,操作系统自己的代码一般是运行在内核态
两种状态的主要区别
处于用户态执行时,进程所能访问的内存空间和对象受到限制,其所处于占有的处理机是可被抢占的 ; 而处于核心态执行中的进程,则能访问所有的内存空间和对象,且所占有的处理机是不允许被抢占的。
为啥要区别
1、区别执行特权指令与非特权指令
在CPU的所有指令中,有一些指令是非常危险的,如果错用,将导致整个系统崩溃。比如:清内存、设置时钟等。如果所有的程序都能使用这些指令,那么你的系统一天死机n回就不足为奇了。所以,CPU将指令分为特权指令和非特权指令,对于那些危险的指令,只允许操作系统及其相关模块使用,普通的应用程序只能使用那些不会造成灾难的指令。
2、操作系统自己的一些数据结构也是不应该向用户暴露的,那很危险
什么时候发生用户态切换到内核态
系统调用
发生中断的情况下会执行内核态的中断处理程序
异常:当CPU在执行运行在用户态下的程序时,发生了某些事先不可知的异常,这时会触发由当前运行进程切换到处理此异常的内核相关程序中,也就转到了内核态,比如缺页异常。
我理解内核态是linux对底层资源的封装,让用户只能通过linux提供的方式(系统调用)使用底层资源,而不能随意操作,防止用户乱搞把系统搞崩了
公共库函数和shell都是对系统调用的封装,用户的应用程序可以直接调通系统调用来使进程切换到内核态,也可以通过调用公用库函数和shell来切换到内核态
用户程序做系统调用涉及到用户态切换到内核态(模式切换),是有代价的:
CPU上下文:CPU寄存器和程序计数器
每个进程有两个栈:用户态栈和内核栈。程序执行到系统调用时,首先使用类似int 80H的软中断指令,保存现场,然后切换到内核态执行系统调用,然后恢复现场。用户态栈切换成内核栈的时候还需要做一些检查等工作,系统调用的返回也需要做一些额外工作,例如检查是否需要调度等,切换cpu上下文本身也有代价
扩展一下:cpu上执行的进程做切换时(进程上下文切换)的代价
线程上下文切换的代价: