簡(jiǎn)單聊聊用戶態(tài)和內(nèi)核態(tài)的區(qū)別
先給不了解內(nèi)核態(tài)、用戶態(tài)的簡(jiǎn)單介紹一下,我們?cè)谑裁磿r(shí)候會(huì)提到這兩個(gè)概念。
例如我們的應(yīng)用程序需要從磁盤讀取某個(gè)文件的數(shù)據(jù),此時(shí)并不是直接從磁盤加載到應(yīng)用內(nèi)存中,而是:
- 先將數(shù)據(jù)從「磁盤」復(fù)制到「內(nèi)核 Buffer」
- 再將數(shù)據(jù)從「內(nèi)核 Buffer」復(fù)制到「用戶 Buffer」
以上就是用戶態(tài)和內(nèi)核態(tài)的概念。首先我們給他下個(gè)定義,這兩個(gè)態(tài)是操作系統(tǒng)的運(yùn)行級(jí)別。
然后我們知道,我們寫的程序,最終運(yùn)行的時(shí)候?qū)嶋H都會(huì)被編譯、解釋成一條一條的 CPU 指令被 CPU 執(zhí)行。
解釋成一條一條的指令
用戶態(tài)、內(nèi)核態(tài)的指令都是 CPU 都在執(zhí)行,所以我們可以換個(gè)說法,實(shí)際上這個(gè)態(tài)代表的是當(dāng)前 CPU 的狀態(tài)。那既然這些指令最終都由 CPU 執(zhí)行,那對(duì)其區(qū)分的理由是什么呢?
那是因?yàn)?,CPU 指令根據(jù)其重要的程度,也分為不同的權(quán)限。有一些指令執(zhí)行失敗了無關(guān)痛癢,而有一些指令失敗了會(huì)導(dǎo)致整個(gè)操作系統(tǒng)崩潰,甚至需要重啟系統(tǒng)。如果將這些指令隨意開放給應(yīng)用程序的話,整個(gè)系統(tǒng)崩潰的概率將會(huì)大大的增加。
再舉個(gè)類似的例子。我們?cè)O(shè)計(jì)一個(gè)類,里面有幾個(gè)很重要的變量,你大概率是不會(huì)把它們聲明成 public 的吧?應(yīng)該聲明成 private,并開發(fā)幾個(gè)專門修改他們的方法,對(duì)傳入的值進(jìn)行一系列的校驗(yàn)之后再去設(shè)置。
上面說到,CPU 指令是做了權(quán)限劃分的, 例如 Intel X86 中將 CPU 指令權(quán)限劃分為了 4 個(gè)等級(jí):
權(quán)限分類
它們之間的權(quán)限的高低程度可以通過這張圖來識(shí)別:
上圖中的 IA 指的是 Intel Architecture
所以可以看到,越靠近的核心的權(quán)限越高。換句話說,權(quán)限由高到低為:Ring0 > Ring1 > Ring2 > Ring3
在 Linux 系統(tǒng)中,由于只有 Ring0 和 Ring3 級(jí)別的指令,所以我們可以對(duì)用戶態(tài)、內(nèi)核態(tài)給一個(gè)更細(xì)節(jié)的區(qū)別描述:運(yùn)行 Ring0 級(jí)別指令的叫內(nèi)核態(tài),運(yùn)行 Ring3 級(jí)別指令的叫用戶態(tài)。
內(nèi)核態(tài)用戶態(tài)
了解了指令集權(quán)限的概念,我們就可以再更正一下上面的描述:什么態(tài)實(shí)際上代表的是當(dāng)前 CPU 正在執(zhí)行什么級(jí)別的指令
知道了用戶態(tài)和內(nèi)核態(tài)的區(qū)別、以及為什么要對(duì)其進(jìn)行區(qū)別之后,我們就可以來看什么時(shí)候會(huì)從用戶態(tài)切換到內(nèi)核態(tài)了。
答案是發(fā)生系統(tǒng)調(diào)用的時(shí)候
那什么又是系統(tǒng)調(diào)用呢?看這張圖
系統(tǒng)調(diào)用 (1)
當(dāng)用戶態(tài)的程序需要向操作系統(tǒng)申請(qǐng)更高權(quán)限的服務(wù)時(shí),就通過系統(tǒng)調(diào)用向內(nèi)核發(fā)起請(qǐng)求。
內(nèi)核自然也會(huì)提供很多的接口來供調(diào)用,例如申請(qǐng)動(dòng)態(tài)內(nèi)存空間。但是申請(qǐng)了內(nèi)存是不是還得考慮釋放內(nèi)存?如果把這塊內(nèi)存管理交給應(yīng)用程序的話,復(fù)雜的管理工作會(huì)給開發(fā)帶來很多負(fù)擔(dān)。
所以庫函數(shù)就是用于屏蔽掉內(nèi)部復(fù)雜的細(xì)節(jié)的,我們的應(yīng)用程序可以通過庫函數(shù)來調(diào)用內(nèi)核的提供的接口,而庫函數(shù)就會(huì)發(fā)起系統(tǒng)調(diào)用,發(fā)起了系統(tǒng)調(diào)用之后,用戶態(tài)就會(huì)切換成內(nèi)核態(tài)去執(zhí)行對(duì)應(yīng)的內(nèi)核方法。
除了系統(tǒng)調(diào)用之外,還有另外兩種會(huì)導(dǎo)致態(tài)的切換:發(fā)生異常、中斷。


































