一、概念
首先我們先來復習一下操作系統的概念和作用
操作系統是用戶和硬件之間的一層媒介程序,為上提供編程接口,為下調用資源,管理驅動,以使用硬件。
從以上的表述我們可以看出OS的兩點作用,第一個是對下直接管理和使用硬件,第二個則是對上提供管理和使用硬件的接口。而在操作系統中,對下管理和使用硬件的那些程序,我們稱之為內核程序,內核程序主要要做的一些事是
- 內存管理
- 文件管理(包括IO)
- 進程調度和進程間通信
- 設備管理(設備分配、設備傳輸控制 、設備獨立性)
而使用內核程序提供的那些接口我們則可以稱之為用戶程序。例如我們的一些網卡或者其他的驅動,也是屬於內核程序對上提供的接口,用戶可以通過這些驅動來管理網卡。因此我們可以規范一下內核程序和用戶程序的概念,以下為我的個人理解
內核程序:操作系統中,可以訪問所有硬件設備,如網卡、內存設備等的一些特殊的高權限的系統程序,
用戶程序:只能有限的訪問部分內存空間,對硬件設備沒有訪問權限的低權限的應用程序或系統程序
有人可能會問了,那我平常用一些自己寫的應用程序,也可以訪問硬盤里的東西,或者開啟對攝像頭的控制,這是不是說明我也能訪問硬件設備呢?當然不是啦!我們平常寫的程序,最后實際上可以看作,運行到了一定的階段,就會托管給內核程序,由內核程序去完成的。
並且在操作系統中,內存空間也被划分成了內核空間和用戶空間。內核程序會始終的占據着內存的一些空間,方便處理器去調用內核程序,而用戶程序是自始至終接觸不到這些內核空間的。
我們運行一個程序的整個流程是這樣的,用戶程序完成一定的事情,然后交由內核程序去處理,內核程序處理完畢之后,將處理的結果或者說處理完成的數據,再交由用戶程序去執行,在整個過程中,用戶程序是完全接觸不到內核空間的。
二、問題
那么問題來了,操作系統為什么要這么大費周章的划分內核和用戶之間的區別呢?我們從實際生活的一個例子出發去探討這個問題。假設你去一家飯店吃飯,點好菜,由服務員通過餐口,轉告給廚房的工作人員,等廚房的工作人員,比如廚師,切菜的人員,把菜做好了,再通過送餐口讓服務員送到你的面前。
我們來分析一下這個過程,在這個過程中,你點菜這個操作,就相當於操作系統中的用戶程序,而服務員和送餐口,就是廚房和外部連接的通道,服務員和送餐口都可以看作是操作系統中的驅動程序,你通過他們來告訴廚房你需要什么菜。然后廚房做菜的這個過程,就是相當於內核處理用戶程序的請求,最后從送餐口送餐的這個過程,就等於是內核處理完之后,將處理完成的數據再轉交給用戶程序。而做菜的過程,對於顧客來說是完全的一個黑盒,用戶不知道里面發生了什么,也無法參與做菜,用戶能看到的,只有從餐口端出來的那盤菜。另外像廚房,倉庫這些重要的地方,你作為一個顧客肯定是進不去的,這些地方只有飯店的核心人員,比如廚師,老板才能進入,你能活動的區域只能飯店的大廳這些公共的區域。這就相當於操作系統把內存的空間,划分為了用戶空間和內存空間,並且強制規定用戶不允許進入內存空間。
因此我們大致上可以得出幾個概念對應例子中的等式,
內核程序 == 廚師 切菜人員,備菜人員,每種程序有不同的功能,同樣的每類職業也有不同的職責,
用戶程序 == 顧客 每個顧客想要的菜都不一樣,對內核的請求也不一樣
內核空間 == 廚房 廚房只允許廚師和備菜的進入,同樣的內核空間也只允許內核程序進入
用戶空間 == 大廳
到了這里,我們就可以來回答一下上面的問題了 “操作系統為什么要這么大費周章的划分內核和用戶之間的區別呢” ,答案是首先操作系統的核心是內核,可以訪問幾乎底層的所有設備和空間,至關重要,為了保護內核的安全,因此操作系統會強制性的用戶程序不允許訪問內核空間,內核空間只有內核程序可以訪問,用戶程序只允許通過內核提供的接口來請求,這樣划分對整個操作系統的穩定性和安全性是一種有力的保護。其實這樣也很好理解,試想如果是一家飯店的廚房,不管是誰都可以隨隨便便的進出,毫無限制,那這家廚房的食品安全問題一定也得不到保障,你還會放心的去這家飯店吃飯嗎?
我們通過上面舉的例子,再來總結操作系統處理數據的整個過程就會顯得好理解很多了。當我們需要讀取一條數據的時候,首先需要發請求告訴內核,我需要什么數據,等內核准備好數據之后 , 再從內核空間拷貝到用戶空間 注意加粗的部分,這兩個階段至關重要
第一階段 :等待內核准備數據
第二階段:數據從內核空間拷貝到用戶空間
那么為什么我們明明是講網絡IO,卻要大費周章的講這么多操作系統的東西呢,因為本身IO操作就是由操作系統控制的,而我們發送一個IO請求,IO讀寫也是要經過以上的這些內核程序執行數據准備和拷貝過程的,如果不把這些講明白了,那么后面我們要提到的,阻塞和讀寫過程必然將是一團霧水。而以上我們所重點強調的兩個階段,則是決定着各種IO模型的條件。包括后面要講到的阻塞IO(BIO),非阻塞IO(NIO),IO多路復用,信號驅動IO,全異步IO(AIO),都是和上面兩個階段以及操作系統知識密切相關的。以上的兩個過程和操作系統整個數據處理流程,務必要理解和記住,之后的文章,都是基於以上OS的整體流程,可以說是網絡IO的基石中的基石
三、總結
-
操作系統為了安全性和穩定性考慮,因此將執行程序分為內核程序和用戶程序,將內存空間分為內核空間和用戶空間,內核程序對下直接對硬件進行使用和管理,對上提供接口給用戶程序使用
-
用戶程序不允許直接訪問內核空間,而是轉交給內核程序,由內核程序處理好,再拷貝到用戶空間供用戶程序使用
-
不管是對於IO還是其他數據處理的操作而言,有兩個重點階段,分別是,一、等待內核准備數據階段,二、數據從內核空間拷貝至用戶空間階段,這兩個階段決定了IO的阻塞於否,非常重要