一文解析為什么進程地址空間中包括操作系統(tǒng)?
今天聊聊進程地址空間這點小事。說到進程的地址空間,大家可能都知道這樣一張圖:

這張圖就是Linux程序運行起來后所謂的進程地址空間,這里包括我們熟悉的代碼區(qū)、數(shù)據(jù)區(qū)、以及堆區(qū)和棧區(qū),今天我們不講解這些區(qū)域,而是重點關注這個地址空間中最上面的一塊區(qū)域——內核,這里的問題是:為什么進程地址空間中要包括操作系統(tǒng)(內核)呢?要想知道這個問題的答案,你需要知道操作系統(tǒng)到底是如何管理內存的?,F(xiàn)代操作系統(tǒng)大都利用虛擬內存系統(tǒng)來管理內存,我們看的上圖,這一段連續(xù)的內存區(qū)域其實只是一個假象,物理內存中并不一定真的存在這樣一個內存布局,利用虛擬內存系統(tǒng)將一些非連續(xù)的內存塊(頁)映射到一段連續(xù)的地址空間——也就是我們看到的上圖,這就是所謂的虛擬內存。我們看到的地址都是虛擬地址,物理內存與虛擬內存的映射關系維護在頁表中,當CPU執(zhí)行機器指令時需要根據(jù)頁表將虛擬地址轉為物理內存地址,但這個過程對程序員來說是透明的,我們看不到這樣的一個轉換過程。那么為什么內核要將自己映射到進程的地址空間呢?我們知道CPU在執(zhí)行指令時是有權限狀態(tài)的,x86處理器有4個權限狀態(tài),操作系統(tǒng)一般使用其中兩個,這就是所謂的用戶態(tài)與內核態(tài),我們寫的程序運行在用戶態(tài),操作系統(tǒng)運行在內核態(tài)。
【文章福利】小編推薦自己的Linux內核技術交流群:【749907784】整理了一些個人覺得比較好的學習書籍、視頻資料共享在群文件里面,有需要的可以自行添加哦?。。。ê曨l教程、電子書、實戰(zhàn)項目及代碼)? ??



在一些場景下,像我們讀寫文件、收發(fā)網(wǎng)絡數(shù)據(jù)等都需要操作系統(tǒng)的幫助,也就是調用操作系統(tǒng)提供的服務,這個過程就是所謂的系統(tǒng)調用,關于系統(tǒng)調用我們在之前的文章中已經(jīng)多次講解過了,在系統(tǒng)調用這個場景下就涉及從用戶態(tài)切換到內核態(tài)。此外還有其它場景涉及用戶態(tài)與內核態(tài)的切換,像中斷處理以及異常處理等。既然你知道我們的程序運行時需要頻繁的進行用戶態(tài)與內核態(tài)切換那么剩下的就簡單了。

如果內核與用戶態(tài)程序位于不同的地址空間,那么當用戶態(tài)與內核態(tài)進行切換時就勢必涉及頁表的切換——從用戶態(tài)進入內核態(tài)需要將用戶進程的頁表切換為內核頁表,而如果從內核態(tài)退出回到用戶態(tài)就涉及將內核頁表切換為用戶進程頁表,切換頁表對于計算機系統(tǒng)來說算是一個不小的開銷。而如果內核與用戶態(tài)程序位于同一個地址空間中,那么上述頁表切換的開銷就可以避免了,這就是為什么內核要將自己映射到進程地址空間的重要原因。好啦,這篇就到這里,希望對大家理解進程地址空間有所幫助。
原文作者:碼農(nóng)的荒島求生
