進程的掛起、阻塞和睡眠

原文
要說掛起、阻塞、睡眠難免讓人想到進程生命週期中的阻塞態或者等待狀態,而掛起和睡眠卻沒有出現在進程生命週期中,說明這三個其實在本質上區別並不那麼大,但是既然稱呼不同,應該就有不同的道理。

先說阻塞,既然它能出現在進程生命週期,必然是每個進程都會經歷的一個階段,衆所周知,進程在運行過程中必然要獲取資源,暫且不說CPU,進程運行肯定要和磁盤進行交互,繼而發生IO操作,IO操作勢必要引起等待,在資源未讀取完成,進程必然要等待,那麼在等待IO完成這個部分就是阻塞狀態。所以從這裏來看,阻塞是一種被動的方式,由於獲取資源獲取不到而引起的等待。

再說睡眠,睡眠就是一種主動的方式,其實個人認爲睡眠和阻塞在一個層次上,爲何這麼說呢?當一個進程獲取資源比如獲取最普通的鎖而失敗後,可以有兩種處理方式,1、自己睡眠,觸發調度;2、忙等待,使用完自己的時間。所以從這裏看,睡眠的確是一種主動的方式,且僅僅作爲一種處理手段。當然睡眠不僅僅用於阻塞,更多的,我們可以在適當的時候設置讓進程睡眠一定的時間,那麼在這裏,就可以發現,睡眠之前,我們已經預先規定了,你只能睡多長時間,這段時間過後,比必須返回來工作。

最後說掛起,掛起也是一種主動的行爲,具體而言,掛起是系統層面對進程作出的合理操作。本來想說調度,但是進程調度作爲專業術語指CPU資源的分配,那麼這裏就說操作。掛起的標誌就是換出到外存,在外存的進程肯定是不能執行的,所以掛起的目的就很明顯,在內存資源不足時,需要把一些進程換出到外存,給着急運行的進程騰地方。掛起傾向於換出阻塞態的進程,也可以是就緒態的進程。只是這個轉換幾乎不會採用,因爲任意時刻,肯定可以找到在內存中的阻塞態進程,但也不能缺少這種直接把就緒轉換到掛起的能力。

其實相比之下,睡眠和其他兩個結合的不太緊密,有資料說掛起釋放內存,而阻塞不釋放內存也有一定的道理。下面結合一個圖看掛起和阻塞的狀態轉換:

這裏寫圖片描述

  • 就緒態:進程在內存中並可以執行。
  • 阻塞態:進程在內存中並等待一個事件。
  • 阻塞/掛起態:進程在外存中並等待一個事件。
  • 就緒/掛起態:進程在外存中,但是隻要被載入內存就可以執行。

    阻塞和掛起之間的相互轉換如下:

阻塞→阻塞/掛起:如果沒有就緒進程,則至少一個阻塞進程被換出,爲另一個沒有阻塞的進程讓出空間。如果操作系統確定當前正在運行的進程,或就緒進程爲了維護基本的性能要求而需要更多的內存空間,那麼,即使有可用的就緒態進程也可能出現這種轉換。

阻塞/掛起→就緒/掛起:如果等待的事件發生了,則處於阻塞/掛起狀態的進程可以轉換到就緒/掛起狀態。注意,這要求操作系統必須能夠得到掛起進程的狀態信息。

就緒/掛起→就緒:如果內存中沒有就緒態進程,操作系統需要調入一個進程繼續執行。此外,當處於就緒/掛起態的進程比處於就緒態的任何進程的優先級都要高時,也可以進行這種轉換。這種情況的產生是由於操作系統設計者規定調入高優先級的進程比減少交換量更重要。

就緒→就緒/掛起:通常,操作系統更傾向於掛起阻塞態進程而不是就緒態進程,因爲就緒態進程可以立即執行,而阻塞態進程佔用了內存空間但不能執行。但如果釋放內存以得到足夠空間的唯一方法是掛起一個就緒態進程,那麼這種轉換也是必需的。並且,如果操作系統確信高優先級的阻塞態進程很快將會就緒,那麼它可能選擇掛起一個低優先級的就緒態進程,而不是一個高優先級的阻塞態進程。

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