進程相關(1)

進程與寫時複製

進程就是正在運行的程序

 我們的系統上可以同時運行那麼多的進程是由誰進行管理的呢?是由內核進行管理的,進程管理是內核一個必要和重要的功能,此外還有網絡管理,TCP/IP協議棧是集成在內核當中的,爲什麼要集成在內核當中?網絡通信是一個很多程序都會用到的功能而且需要與硬件打交道,如果把TCP/IP協議棧放到用戶空間的話效率太低。

爲什麼要創建子進程?在討論進程管理之前我們要明確爲什麼要創建一個子進程,當一個進程面對一個比較複雜的任務的時候就會在原來進程基礎上創建一個新的進程,把這個複雜的程序委託子進程完成,當子進程把委託給給它的的任務完成之後會把結果返回到父進程。

進程是如何創建的?內核並不負責進程的創建,內核在cpu上運行起來掌管了一切之後,意味着內核空間啓動,開始創建第一個進程init(初始化進程),init啓動完成之後意味着用戶空間創建完成,init負責創建用戶空間的進程的管理,當我們創建一個進程的時候是init按照自己的樣子進行創建的或者按照父進程創建的。內核就相當於上帝而init進程就相當於上帝派下來管理人間事物的使者,使者大人負責創建進程和回收進程這類的雜事,當然使者大人也不是萬能的,它也需要產生一個又一個進程幫助它完成任務,還有對於向內核申請資源的大事使者大人也不敢壓下,還是會向內核報告,因爲對於分配資源這種事,也只有內核才能完成,其他任何人都沒有這個能力,在linux當中,內核就是上帝。

父進程創建子進程時請init程序批准,並向內核申請資源(cpu和內存的使用),子進程創建之初是與父進程共用一個用戶空間的,當子進程自己獨立之後要使用新的內存空間和數據進或者需要去修改自己的數據的時候父進程不允許的,因爲一旦修改了你進程就沒辦法用了,然後把父進程的數據複製一份到子進程的用戶空間單獨單獨修改,這也就是寫時複製。

資源分配和進程銷燬

對cpu的分配 ,進程有那麼多個,但是cpu只有一個,怎樣進行分配呢?通過對cpu進行切片分時,一個進程使用一小會兒,比如說是5毫秒,五毫秒到了之後 不管這個進程有沒有完成都要退下讓下一個進程上去運行。但是如果有進程佔着cpu不願意下去呢?這是不可能會發生的情況,內核掌握一切,運行五毫秒之後不管怎樣都會一腳把這個進程踢下去的。把當前的進程踢下去之後下次再運行的時候肯定要是沿着上一次的沒有運行完成的地方繼續運行,但是在什麼地方保存着進程當前的狀態呢?進程的運行狀態保存在cpu的寄存器當中,當進程從cpu上退下之後其實是把進程的狀態保存到內核的任務結構體當中,當又輪到該進程使用cpu的時候可以快速讀取內存當中此進程的狀態,然後沿着上一次執行的痕跡繼續向下運行。保存狀態的過程的稱做保存現場,恢復狀態的過程稱做恢復現場,在內核當中保存的進程狀態信息的容器叫做“任務結構體(內核用來存儲進程狀態的固定格式)”在用戶空間是可以通過命令查看到些任務結構體的。如果好多個任務結構體放在一塊就組成了一個鏈表。進程是白髮人送黑髮人的,父進程需要完成一個複雜任務時才創建子進程,完成任務之後返回結果,子進程完成之後由父進程進行銷燬, 子進程在執行任務的時候父進程處在等待狀態,父子關係保存到任務結構體當中,其優先級也保存到任務結構體當中,如果父進程沒有來得及銷燬子進程父進程就掛了的話也沒有問題,因爲有“上帝的使者”的存在,上帝的使者可以銷燬這個進程。

進程是有優先級的.這個世界沒有絕對的公平,在計算機的世界也是一樣的,也是有優先級的。舉個例子:比如一個ping請求到達主機,cpu就必須立刻做出迴應,如果這個ping請求沒有任務特權的話(不能立刻得到迴應),當cpu有空閒時間來處理這個ping請求時,可以這個ping請求早就請求超時了,所以ping請求的優先級是比較小的,比較小就意味着優先級越高,能夠被cpu優先執行。再比如:主機忽然斷電了,還好我們的主機還有備用電源,當然也會有相應的進程,當這個進程查看到有斷電情況會立刻做出決斷,這種進程的優先級也是比較高的。

NICE

內核把進程的優先級劃分了固定的個數0-139,共140個優先級,1-99是實時優先級,數據越大優先級越高,這一部分優先級是由內核直接管理的,root也不能插手。 100-139靜態優先級:數字越小,優先級越高。相同優先級排成一列,這樣的話無論是有多少個進程內核只要掃描一上這個鏈表都知道他們的優先級了。

一個進程優先級高意味着下面兩點:

   獲得佔用cpu更多的時間

   優先獲得運行的機會

這一優先級範圍內的進程root都是可以調整的。

image.png

nice是範圍是-20到19,分別對應100-139,還是nice值越小優先級越高,調整nice值就相當於調整優先級,一個進程的默認優先級是0. 如果一個進程的NI從0調整到-5的話,就相當把進程的優先級就從120轉換成了115,0對應120,120-5=115。普通用戶只能讓自己的進程的優先級值變大,變大意味着優先級降低,只有root可以隨意的更改,當然也只能在100外調整。

當內核需要調用一個新的進程到cpu的時候就從此鏈表當中選擇,當在cpu上運行完之後 會放到另一個鏈表當中,另一個鏈表的構造同這一個是一樣的,當這一個鏈表上所有的進程都運行完了之後就向另一個鏈表當中選擇進程去cpu運行。

對內存的分配,進程有那麼多,內存也只有一個,怎樣進行分配呢?我們知道用戶空間的進程是不能直接與硬件打交道的,都要經過內核,內核會把內存給分成片,一片佔據4K,這一片其實就是一個頁框。內核把頁框進行虛擬,虛擬成線性地址空間,當程序進行開發的時候,程序員假設內存有4G或者8G開發程序,其實一個程序是不能一下子把內存條都佔用了,進程佔用的其實是線性地址空間,這個線性地址空間是內核用來欺騙程序的,這個程序能使用多少真正的內存空間就分配給它多少空間,但是在進程看來它佔用的是整個內存條,進程的存在於內核給它編織的虛擬世界當中。當真正的內存沒有頁框可以使用了,內核會掃描一下整個內存當中的頁框,通過一個算法計算出使用最少的的頁框放到swap分區,那麼如果是這樣做了,當真正使用這個頁框的時候內核是怎樣操作的呢?我們前面提過內核當中有一個進程任務結構體,這個結構體不僅保存了進程的狀態還保存了進程使用了哪些線性地址空間還有對應的物理地址空間,當這個程序調用到cpu進行運行的時候,內核會通過讀取這個任務結構體裏面此進程對應的地址空間把頁框從swap分區中重新加載到內存當中,在此過程當中會有一個異常就是缺頁異常,因爲內存當中的頁框被調用到了swap當中了,不能馬上找到這個頁框,需要去硬件當中調用。

進程有沒有可能擺脫內核的控制?進程是沒有辦法擺脫內核的控制,除非內核有漏洞,當進程由用戶空間轉向內核空間的時候會發生一次軟中斷 ,這一次中斷其實就是讓內核醒來的操作

IO

IO分兩個步驟,硬件>內核>進程

當我們在shell當中cat一個文件時候,cat 進程會請求內核幫它從硬盤當中讀取出文件,因爲只有內核可以與硬件打交道,當內核從硬盤當中讀取了這個文件的內容之後 再把這個內容放到cat進程當中。也就是說,進程發起調用等兩段時間,第二段纔是真正的IO過程。

image.png

通過上圖我們可以看出IO的一些情況,當第一次我們備份/etc/目錄時,所花費的時間很長,因爲這一次全新的IO,cp命令向內核申請,內核把數據從內核當中調用出來到內核空間,然後再分配給進程,這是兩段過程。當第二次的時候因爲數據已經在內存當中還沒有清除,此時的IO就成了一段而不是兩段,所以速度快了很多。


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章