在研究Synchronized的锁升级机制时,有一句话说:
.....所以从上面描述可以得出,监视器锁就是monitor它是互斥的(mutex)。由于它是互斥的,那么它的操作成本就非常的高,包括系统调用引起的内核态与用户态切换、线程阻塞造成的线程切换等。因此,后来称这种锁为“重量级锁”。
这里提到了依据用户态与内核态的切换,我就了解一下:
有的说这是两种CPU的状态,也有人说是操作系统的运行状态,有点不大清楚
1、两者区别以及划分的原因:
用户态:运行用户自己编写的程序,用户可使用的资源受到极大的限制
核心态:运行操作系统的程序,可以调用一切资源为该服务运行
现在操作系统的运行级别一般可分为R0-R3四种级别,其中CPU级别在R0表示核心态,R3表示用户态。Linux中一般只使用R0和R3级别。
特权指令:只能由操作系统使用的指令,如中断、清理内存、设置时钟。
非特权指令:可以被用户使用的指令。
划分特权和非特权的原因:操作系统中发一些指令属于极其危险的级别,如清理内存、设置时钟等。如果允许用户随意调用,将发生无法预估的灾难,导致系统奔溃。
2、何时进行两者的切换:
- 系统调用:当处于用户态的进程出于某种需求,需要操作系统提供一些服务时,申请进行系统调用,如父进程fork一个子进程。系统调用的内置机制是一种软中断。
- 异常:在执行用户程序时 发生无法控制的错误时,系统会自动切换成核心态,如除零异常。
- 外设中断:当外设发送请求时,如果cpu处于用户态,则会暂停执行下一条指令,转而去执行中断服务程序。此时发生的就是用户态到核心态的切换。
以上三种触发方式,本质上的切换操作是一致的,没有任何区别,都是相当于执行了一个中断相应的过程!!因为系统调用实际上最终也是“中断机制”实现的,而异常和中断的处理机制基本上也是一致的!!
3、判断操作系统处于何种特权级别:
CS寄存器中最低两位保存当前代码的执行级别。
涉及到“用户态切换到内核态”的步骤主要包括:
1. 从当前进程的描述符中提取内核栈的ss0及esp0信息。
2. 使用ss0和esp0指向的内核栈将当前进程的cs、eip、eflags、ss、esp信息保存起来,这个过程也完成了有用户态到内存栈的切换过程,同时保存了被暂停执行的程序的下一条指令。
3. 将先前有中断向量检索得到的中断程序的cs、eip信息装入相应的寄存器,开始执行中断处理程序,这是就转到了内核态的程序执行了。
总结:
1. 计算机系统中有“操作系统程序”和“普通用户程序”。
2. 操作系统程序执行就是在“内核态”下执行的。
3. 普通用户程序就是在“用户态”下执行的。
4. 内核态可以使用所有的硬件资源,用户态不能直接使用系统资源,也不能改变CPU的工作状态,只能访问用户程序自己的存储空间!
5. 为了安全和稳定性,操作系统程序是不能随便访问的!
6. 引起“用户态切换到内核态”的本质就是“CPU实行了一次中断相应”!