理解用户模式和内核模式(译)

来源:互联网 发布:反稀释 加权平均 知乎 编辑:程序博客网 时间:2024/06/18 11:31

原文来自:https://zryfish.github.io/computer%20related/2015/08/28/user-mode-and-kernel-mode/


###理解用户模式和内核模式

本文出处: http://blog.codinghorror.com/understanding-user-and-kernel-mode/

绝大多数的操作系统都可以显示CPU的使用情况。在Windows上,我们可以使用任务管理器(Task Manager)查看.CPU UsageCPU的使用率(CPU Usage)大体上可以表示CPU花在处理非空闲任务的时间的比率。这只是一种简化的说话。实际上,在所有的现代操作系统中,CPU是在两种不同的模式下运行的:

  1. Kernel Mode
    在内核模式下,代码具有对硬件的所有控制权限。可以执行所有CPU指令,可以访问任意地址的内存。内核模式是为操作系统最底层,最可信的函数服务的。在内核模式下的任何异常都是灾难性的,将会导致整台机器停机。

  2. User Mode
    在用户模式下,代码没有对硬件的直接控制权限,也不能直接访问地址的内存。程序是通过调用系统接口(System APIs)来达到访问硬件和内存。在这种保护模式下,即时程序发生崩溃也是可以恢复的。在你的电脑上大部分程序都是在用户模式下运行的。

如上图所示,可以让任务管理器显示内核的CPU占用时间。绿色的线表示总的CPU时间,红色的线表示内核使用的CPU使用,两者之间的间隔就是用户程序使用的CPU时间。

上面所说的两种模式不仅仅是字面上的区别,它们是受CPU严格制约的。如果在用户模式下,程序尝试做些其权限以外的事情,比如说,执行一条高权限的CPU指令,修改其被禁止访问的内存,这时一个可捕获的异常就会抛出。但这只会导致这个倒霉的应用程序崩溃,而不会让你的整个系统崩溃。这就是用户模式的意义所在。

x86 CPU提供4种保护层级: 0, 1, 2 and 3. 实际上,只用0级(内核)和3级(用户程序)被使用到了。

x86 rings

有点让人疑惑的是,如果我们只使用了两种保护层级(内核,用户程序),那些可以让我们访问显卡,键盘,鼠标,打印机的设备驱动代码应该在哪层运行。为了最佳的性能,设备代码应该运行在内核模式?还是为了追求稳定,让它们运行在用户模式下?至少在Windows操作系统上,答案得视情况而定。设备驱动代码可以运行在用户模式,也可以运行在内核模式。如今,大多数的设备驱动代码都运行在用户模式下,当然也有例外,为了最佳的性能,显卡驱动是运行在内核模式下的。不过时代在变,在Windows Vista系统中,显卡驱动就已经被分成了用户段和内核段。这或许也是为什么会有游戏开发人员抱怨Vista平台上的游戏的性能会低上10%左右。

这些模式之间的界限一直不是很明确。什么样的代码应该运行在用户模式下?什么样的代码应该运行在内核模式下?或者我们可以再加一个地下室,虚拟化的要求催生了一个新的保护层级,-1级,在所有保护层级之下,这就是我们熟知的x86的硬件层虚拟化。

用户模式总的来说是有益无害的,但是代价却是昂贵的。在用户模式和内核模式之间的转换代价是非常高的。比如说,程序抛出异常通常都是很耗时的。异常意味着模式的转换。当然了,如今的计算机的资源如此丰富,我们很少去关心模式转换的代价。可是,当你的程序需要的资源变多时,你就需要为这些事操心了。

区分用户模式和内核模式最典型的例子应该要数webserver了。在一些开源的web服务器将代码放在内核模式运行而赢得行业benchmark的胜利后,Microsfot也将IIS 6一些核心的功能移到内核模式下运行。如果你要问我的看法的话,我会说这是一场没有意义的较量,因为双方都只是针对静态的HTML做了内核优化。但就是这样,不管是针对benchmark还是其它的竞争。

CPU对用户模式和内核模式的严格限制对于用户来说是透明的,其实也就是程序经常崩溃和电脑经常崩溃的区别。这就是我们这些写出崩溃代码的程序员们口中所说的”进步”。所以,我代表各地的程序员们,对”用户模式”说句谢谢。你真棒!


原创粉丝点击