進程、系統調用

「多問,爲什麼?」能夠幫助你深入理解各種你想要知道的東西?什麼,你不信,那我們一起試試吧。

1. 進程

1.1 爲什麼需要進程

不是進程需要我們,而是我們需要進程。想象一下,現在提供一個操作系統,而你想要通過操作系統控制各種資源,包括處理器、內存、磁盤等,你會怎麼做?

  • 將各個資源排隊,每次都取一類資源處理,最後整和到一起使用,這得是一種多麼低效的手段……
  • 提前打包好各種可能使用的資源,每次使用申請一個已經包裝好各個資源的殼子出來,這就聰明很多了嘛

結論:操作系統作爲硬件的使用層,提供使用硬件資源的能力,進程作爲操作系統使用層,提供使用操作系統抽象出的資源層的能力。

1.2 進程的一生

1.2.1 什麼是進程

進程,是指計算機中已運行的程序。進程本身不是基本的運行單位,而是線程的容器。程序本身只是指令、數據及其組織形式的描述,進程纔是程序(那些指令和數據)的真正運行實例。

概念性的東西,筆者一向會有點抓不住重點,所以畫個重點:

  • 進程是處於執行時期的程序。

  • 內核調度的對象是線程,不是進程。

  • 概念摘自維基百科,詳細參考可直接戳

1.2.2 進程 — 生

在創建一個進程的時候,我們到底創建了什麼?

答:其實就是一個數據結構—task_struct,這個數據結構記錄進程運行需要的各種資源,像打開的文件描述符、掛起的信號量、內核內部數據、處理器狀態等(ps 反正就是這個進程創建需要的各種資源……

進程創建後如何表示?

答: 爲了能夠找到上面創建的 task_struct,內核用雙向循環鏈表存儲 task_struct,並通過一個唯一的 PID 來標識每個進程。 (ps ?思考下:操作系統中的進程數量可以無限增加嗎?

進程如何創建?

進程創建被分解到兩個單獨的函數中去執行:

  • fork() 拷貝當前進程創建一個子進程
  • exec() 負責讀入可執行文件並將其砸入到地址空間開始運行

注意:寫實拷貝,是一種推遲甚至免除拷貝數據的技術。父子進程會共享同一份拷貝,只要在需要寫入的時候,數據纔會被複制。寫實拷貝的出現是因爲直接把所有資源複製給新的創建進程效率太低,因爲拷貝數據有可能根本不共享或者新進程打算執行一個新的映像,那麼所有拷貝都會失效

1.2.3 進程 — 死

爲什麼死,還需要單獨說呢?死了不就一了百了,什麼都不用管了嘛……,身體髮膚受之父母,總得通知下你父母吧。

談談進程花式死法吧?

  • 自殺 —— 顯示或者隱示的調用 exit() 系統調用
  • 他殺 —— 信號量(ps 你執行了kill 什麼,害死了活潑可愛的進程……)

但是無論哪種死法,你總得需要釋放下創建的時候你申請的各種資源

清理完資源你就真的宣告死亡了嘛?

答:世界這麼複雜,你想死也由不得你不是,所以進程死亡的時候清理資源和刪除上面創建的 task_struct 是分開進行的,所以刪除 task_struct 是在下面佈置執行完再進行的。

  • 假如父親健在,通知父親兒子死亡的消息
  • 假如父親先掛掉了,找到公共養父進程 (init) 通知兒子死亡的消息

疑問:筆者其實沒想通爲什麼清理工作和刪除 task_struct 要分開進程……

2. 系統調用

操作系統提供進程與操作系統進行交互的一組接口,這組接口被稱爲系統調用,提供以下能力:

  • 進程受限的訪問硬件設備
  • 創建新進程
  • 與已有進程進行通信
  • 申請操作系統其它資源的能力

2.1 爲什麼需要系統調用

人跟人之間是沒有信任的,你怎麼確定進程能夠按照你的想法使用操作系統,所以

  • 系統調用提供了一種硬件的抽象接口,使得進程不需要關係磁盤類型和介質等底層的信息。
  • 作爲操作系統和進程的中間層,操作系統可以基於權限、用戶類型和其他的一些規則對訪問進行限制。

注意此處均以 linux 的操作系統爲例,該系統提供系統調用接口有幾百個,跟接口設計名言「提供機制而不是策略」,系統調用抽象出完成某種確定目的的函數,至於這些函數怎麼用不是操作系統關係的。

2.2 系統調用怎麼做

每個系統調用都被賦予一個系統調用號,通過系統調用號可以關聯到系統調用。系統調用表記錄了所有已註冊過的系統調用列表。

進程在創建的時候會申請 4G 大小的虛擬內存,具體佈局見下圖。

在這裏插入圖片描述

內核駐留在受保護的地址空間。基於安全性的考慮不允許用戶進程直接訪問,所以系統調用執行的時候是通過軟中斷實現的,通過引發一個異常來促使系統切到內核態去執行處理程序,此時異常處理程序實際上就是系統調用的處理程序。

注:進程只有通過系統調用 和 異常處理程序 才能夠訪問內核。

進程上下文: 當一個進程執行系統調用或者觸發某個異常,它就陷入內核空間。內核「代表進程執行」處於進程上下文。

中斷上下文: 不是進程級別的,爲內核所有,具體概念理解改日來補充吧,主要是筆者也木有理解的很清楚

3. 總結

筆者其實想把進程調度也加入到這篇文章的,但是想了下進程調度比較複雜,其實可以單獨列出來分享一下(ps 還有就是一直被保安大叔外放的歌曲打斷思路,我太難了……

4. 參考資料

  • 《Linux 內核設計與實現》3、5 兩章
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章