進程管理01
進程的概念
進程是計算機中一個非常重要的概念,在整個計算機發展歷史中,操作系統中程序運行機制的演變按順序大致可以分為:
- 單道程序:通常是指每一次將一個或者一批程序(一個作業)從磁盤加載進內存,CPU必須等待I/O完成后才可以進行執行,CPU利用率低。
- 多道程序:講多個作業調入內存后自動處理,但是單道程序和多道程序均無交互性,可控性差
- 進程:程序+PCB(狀態周期描述)+數據集
- 線程
單道 --> 多道系統
從單道程序演化為多道程序就是CPU的高速與I/O的低速有着顯著矛盾,因此引入了多道程序作為解決。舉一個例子,在單道程序中,倘若I/O沒有完成,那么CPU就會一直處於空閑狀態。但是在多道程序中,當某程序在占用CPU的時候,其余程序可以開始進行I/O請求,互不干擾,這樣就減少了在I/O中CPU的空閑。當某個程序釋放CPU后,下一程序繼續占用CPU。
在多道程序中,經常會有這種情況,例如某程序需要監測輸入值,那么,該程序就會委托I/O系統去取值,那么在取值完成前,該程序並不需要占用CPU,那么程序會由於I/O阻塞主動放棄CPU,並且進入執行隊列尾部,此時CPU會按出隊列的順序依次分配。
多道程序的狀態:
多道程序的調度
多道程序 --> 進程
進程就是在程序中加入一些描述程序狀態的塊(PCB)
從多道程序演化為進程的過程中是通過提高並發性,從而進一步的提高CPU的利用率。事實上也就是在多道程序死板的調度機制中靈活的進行控制程序運行的順序等。實現的功能便是PCB的監控。
進程的狀態:
進程的調度:
進程 --> 線程
在進程之下,我們引入了線程。在說線程之前,我們引入那么一個問題,假定你制作了一個即時通訊的程序,如果你只是用一個進程去控制程序運行,會發生什么?事實上這里發生的事情你有時候可以在一些小廠商做出的低劣游戲中發現這一問題。我們在有些制作不好、歷史久遠或者代碼質量差的游戲中,經常能發現,一旦網卡了,整個游戲甚至都會卡頓甚至無響應,游戲的渲染也受到了很大的影響。有時候是因為網絡一直在嘗試發包導致,但是更多時候是因為進程調度問題。可是為什么網絡是基於外部的,卻可以影響內部的引擎渲染之類的功能呢?原因就是我們之前講過,請求網絡是一個明顯的I/O過程,假設網絡不好,那么我們的程序一直處於I/O阻塞的狀態下,從而放棄CPU,那么我們渲染的代碼也會遲遲得不到運行。會到我們之前的問題,假設你只是用一個進程去制作了即時通訊軟件,一旦網絡丟包之類的網絡故障發生時,你的程序很容易卡頓。
說了那么多,我們應該如何去解決這個問題?很自然的我們會想到使用多進程去制作一個軟件,那么其中一個進程發生阻塞的時候,我們其余的進程會繼續占用CPU,則整體運行並不會受太大影響。但是這種方法需要占用大量的時空,因為進程的調度是依賴PCB以及PCB的監控程序,進程切換過程中,上下文切換也會導致PCB狀態切換,需要花費大量的時間進行查詢、修改等操作,並且內存棧的使用也會過於頻繁導致空間消耗,並且在操作系統中,PCB的數量是有限的,因此使用多進程並不是一個號的方法。
這里我們就引出多線程的方法,進程就成為了線程的一個容器,且進程和線程可以同時存在,線程幾乎不占用多少空間,整體也比進程小的多,那么對線程的調度開銷就會遠比進程小得多。進程的數量也減少了,那么整體系統的壓力也小了。
進程和程序的區別
- 程序是一段代碼編譯后的產物,在執行過程中被拷貝至內存,通常是靜態不變的,進程在運行過程中是會發生狀態轉變,通常認為是動態的。進程是對程序一次執行的過程。
- 程序和進程是多對多關系,例如同時執行兩個一樣的程序和操作系統的GUI繪圖渲染與各個可視化程序的關系。你可以在任務管理器中發現這些關系
進程的特征
- 並發性:與OS的並發一致
- 異步性:與OS異步一致
- 動態性:進程在運行過程中是會發生狀態轉變,通常認為是動態的。
- 結構性:使用了PCB組成
- 獨立性:在資源分配過程中,各個進程是獨立分配。例如各個進程在內存中的位置都是獨立的。
進程的組成
通常我們只考慮為PCB+程序或PCB+指令段+數據段。這里涉及到的指令段和數據段是什么呢?
指令段就是具體的操作邏輯,而數據段就是存儲的具體數據值,他們通常都存儲在棧上。例如有一段代碼:
public int Add()
{
return 3+4;
}
這段代碼在進程中會存儲函數指針,也就是程序的具體內存位置;3和4將會作為數據段存儲在獨立的堆棧中,而 ‘+’會存儲在指令段中。
PCB的組成
- PID:進程的唯一標識
- 狀態:進程五個狀態中的一種
- 優先級:用於控制進程的執行順序
指令段的組成
- 運行地址:指程序代碼在內存中的位置
- 外存地址:程序在存儲設備上中的位置
- 代碼段指針:程序指令段在內存中的具體位置
- 進入內存時間:進入時間
數據段組成
- 堆棧指針:用於存儲數據的地址
- 數據段指針:數據段代碼的地址
進程的組成
進程運行分析
對於一個進程或程序需要運行,以下三個東西是必不可少的:
- PCB
- 內存
- CPU
進程的狀態:
- 對於新建-->就緒過程,進程會向操作系統申請內存和PCB,同時將進程排入隊列使得這個非常的簡單。
- 就緒-->運行過程,操作系統需要向進程分配CPU資源使得程序運轉。反過來則是因為某些原因使得進程不再占用CPU,通常是時間片用完。
- 運行-->阻塞過程,通常是有了一個I/O請求導致了進程的阻塞中斷。
- 阻塞-->就緒過程是I/O完成后重新喚起進程,使進程重新進入就緒隊列
- 運行-->完成則是歸還內存並刪除PCB。
在狀態轉變的時候,通常就是要實施以下三步:
- 分配(申請)內存或CPU
- 回收
- 修改PCB
如果我的文章幫助了你,請給我一個三連和star。