在計算機中,進程就是一段程序的執行。數據結構
進程包括:併發
1)執行這段程序所須要的代碼 學習
2)執行程序所須要的相關數據spa
3)操做系統管理進程所須要的信息——進程控制塊操作系統
ok瞭解了進程的基本概念,接下來就要去了解進程的具體組成結構和操做系統如何去控制進程線程
在看進程的狀態以前,先複習一下,進程在系統中如何運做。設計
操做系統經過一種分時機制實現多進程的併發執行。這裏用到了併發這個詞而不是並行,是由於針對單處理器的計算機來講,歷來就不會有並行狀態發生,一個處理器同一時間內只能處理一段代碼,也只能完成某一個任務,是不可能實現任務的並行執行的。3d
爲了提升計算機的用戶體驗,也爲了合理的利用計算機資源,讓CPU在最大限度下處於一直工做的狀態,操做系統經過執行一種叫作輪轉的方式,爲每個進程分配一個最大運行時間(時間片)形成一種多進程併發執行的狀態。blog
因此,在某一個時間點上,看似同時在運行的多個進程,只有一個,或幾個(多處理器)進程在運行,其餘的進程處於其餘狀態。隊列
那麼進程到底擁有幾個狀態?
進程的狀態會由於不一樣操做系統的實現不一樣而略有改變,但最基礎的是五種狀態:
1.新建狀態:剛剛建立進程,操做系統尚未把它加入到可執行的進程組之中。(也就是,進程雖然建立,可是還沒有運行,還沒有加入任何隊列之中。——隊列的概念稍後會提出)
2.就緒態:進程作好了準備,等待分配處理器。
3.阻塞態:進程在某些事件發生以前不能執行:如IO操做
4.運行態:該進程得到了時間片,擁有控制處理器的權利,正在運行相關程序。
5.退出:操做系統從可運行進程組中釋放進程,或者他自身的緣由中止了,或者由於某些緣由取消。
解釋:
爲何會有阻塞狀態?
由於計算機存在着個各個部位運行速度的不均衡,處理器的運算速度經常是IO設備的上千倍上萬倍,有些IO設備的速度尤爲慢好比打印機。若是某些進程須要使用IO設備的返回結果,那麼處理器必須等待IO設備完成任務,並返回執行結果,在這期間處理器徹底沒有工做,這就形成了計算機資源的浪費。所以,操做系統實現了一種阻塞機制,當一個進程須要用到IO等耗時的工做時, 進程阻塞。在IO完成時會產生一個IO中斷,告訴操做系統,這個事件已經完成,剛纔那個或者那些須要等待的任務能夠繼續進行了,操做系統會根據分派器決定哪個進程將會繼續執行。
進程如何開始?
一般有4個事件會致使建立一個進程。
1)新的批處理做業
2)交互登錄
3)操做系統由於提供一項服務建立
4)由現有的進程派生
進程如何終止的?
有不少行爲都能形成系統的終止,進程在任何狀態下都能被終止。
終止的原意多是,交互系統下用戶的終止,也多是自身產生的錯誤或者硬件產生的錯誤。
什麼是搶佔?
搶佔這術語被定義爲收回一個進程正在使用的資源。這是一種可能發生的運行->就緒狀態的轉換緣由。當阻塞隊列中擁有一個優先級高於當前執行的進程,當阻塞事件發生,高優先級進程恢復到可運行狀態,就有可能搶佔運行進程的資源,讓當前進程變成就緒狀態。
線程執行軌跡
中斷髮生後程序計數器(PC)從新賦值程中斷處理程序,中斷處理程序會委託分派器決定接下來執行的進程。
什麼是隊列?
隊列是操做系統維護進程執行的數據結構,使用FIFO的結構保存即將執行的任務。
最基礎的隊列由一個就緒隊列和一個阻塞隊列組成,當一個進程的時間片用盡且沒有阻塞的話會被插入就緒隊列,而且從就緒隊列中取出一個新的進程進行運行。當一個進程被阻塞,會被放入阻塞隊列。這樣有一個很明顯的缺點,當發生一個阻塞事件,操做系統會掃描整個阻塞隊列,將等待這個事件的進程放入就緒隊列,一個真正的操做系統阻塞隊列中經常有很大量的阻塞進程,這樣會致使效率十分的低下。
因此,通常來講,等待一個事件的阻塞進程放入單獨的隊列之中,當事件發生,整個隊列放入就緒隊列之中。
同理,多優先級也會維持多優先級隊列以方便管理。
除了剛纔說過的五種進程狀態,還有一類狀態叫作掛起態。掛起態並非一個狀態,而是一對。首先解釋一下什麼叫掛起態。
掛起態的產生仍是由於計算機資源的不足,計算機內存是一種昂貴的資源,內存大小的發展速度徹底跟不上程序常駐內存大小的發展速度,因此這就極大地限制了同時可以運行的進程的數量。並且,計算機IO的速度比起CPU計算的速度仍是太慢,在某個時間點,隊列中可能徹底沒有就緒狀態的進程,所有都在等待IO。所以操做系統經常加入一個掛起態,用來「驅逐」等待IO的進程,提供足夠的空閒內存供更多進程使用。
這裏涉及到一個交換的概念。交換是一個IO操做,當內存中全部的進程都處於阻塞狀態時,操做系統能夠把其中一個進程置於掛起狀態,將其內存佔用轉移到磁盤,內存釋放的空間能夠被調入另外一個進程使用。
接着思考掛起的問題,當內存擁有足夠的空間,這時候能夠選擇開啓一個新的進程或者從掛起狀態的進程中選擇一個用來運行。可是掛起狀態的進程在掛起前是阻塞的,如何判斷他如今能否執行呢?所以要爲掛起態的進程再進行細分,以肯定被掛起的進程是不是就緒的。這樣就誕生了2*2 = 4種不一樣的狀態
就緒態
阻塞態
掛起阻塞態
掛起就緒態
當一個阻塞事件發生,等待此事件的阻塞進程從阻塞隊列進入就緒隊列,等待此事件的阻塞掛起進程進入就緒掛起狀態。當內存中擁有足夠的空間能夠容納一個新的進程時,就緒掛起狀態的某一個進程就有可能從新回到就緒狀態運行。
這裏所說的掛起狀態的轉化,是在簡化了操做系統實際的轉化過程以後總結的。
在實際的操做系統中,是否掛起還考慮到優先級問題,若是就緒掛起隊列某進程中擁有比就緒隊列中更高的優先級,那麼就緒隊列中也有可能會有進程被交換到掛起狀態,以供更高優先級的進程繼續執行。
若是這個過程當中涉及到虛擬內存,設計的話會更加複雜,留做之後討論。
在學習進程的管理以前要了解一下操做系統爲了管理進程維護管理的資源
操做系統維護着4中不一樣的表:
內存:用於追蹤內存和外存。內存表包括如下信息:
1.分配給進程的內存
2.分配給進程的外存
3.內存塊或者虛擬內存塊的任何保護屬性。
4.管理虛擬內存所須要的任何信息
IO:IO表管理的計算機系統中的IO設備和通道
文件:提供文件是否存在,文件在外存中的位置
進程表 剩餘部分將討論的就是進程表。
操做系統要對進程進行管理,首先要知道進程的位置,再者要知道管理時所須要的進程屬性。
一個進程的物理組成是程序、數據、棧、屬性所佔用的內存。這些元素組成了進程映像。
進程屬性有能夠細分爲一下三類:
進程標識信息:用於標識一個進程的屬性,包括(惟一標識符、父進程標識符、用戶標識符)
處理器狀態信息:用於進程切換的時候保存運行時處理器狀態的屬性。
進程控制信息:控制和協調各類活動須要的額外信息。
進程控制塊被一個統一的處理例程訪問,目的是控制對進程控制塊的訪問,以保護進程控制塊。
執行模式
大多數操做系統至少支持兩種執行模式,有些指令只能在特權模式下執行,有些內存區域也只能在特權模式下才能訪問到。
非特權態常被稱做用戶態,特權態被稱做系統態或者內核態。
使用不一樣執行狀態的緣由是爲了保護系統,不讓用戶去執行特定的可能影響系統的指令。
處理器如何判斷當前是什麼執行模式?
PSW程序狀態字(處理器的一部分)中有一位表示執行模式,當用戶調用一個系統服務或者中斷處於發了系統例程的執行時,執行模式設置成內核態,返回時會被設置成用戶態。
進程的建立
1.給進程分配一個惟一進程標識符
2.給進程分配空間
3.初始化進程控制塊
4.設置正確的連接。將新的進程放入正確的調度隊列之中。
5.建立或者擴充其餘數據結構
進程的切換
分析一下進程的切換,進程的切換在宏觀上(相對宏觀)就是操做系統指定另外一個進程爲運行態,而且把控制權交給這個進程。但這會引起不少新的問題:
1.何時切換進程?
2.模式切換和進程切換有什麼區別和聯繫?
3.切換一個進程必須對數據結構作些什麼?
本片爲文章剩下的部分就是解決這幾個問題
什麼時候切換進程?
簡單點說,只要操做系統有控制權,就能切換進程。
操做系統會在如下時間從正在運行的進程中獲取控制權:
1.中斷 常見中斷(時鐘中斷(時間片用盡),IO中斷(IO完成),內存失效(缺頁,和IO同理,至於什麼叫缺頁,虛擬內存會涉及到這個名詞))
2.陷阱:正在執行的進程所發生的錯誤
3.系統調用:顯式的請求
模式切換
若是存在一個未處理的中斷,會發生如下的工做
1.把程序計數器置成中斷處理程序開始的地址
2.從用戶態切換到內核態,使得中斷處理代碼能夠包含特權指令。此時,被中斷的進程上下文保存在被中斷程序的進程控制塊中。
進程切換
很明顯,進程轉換和模式轉換不一樣,模式切換能夠不改變正在運行的進程狀態,在這種狀況下保存和恢復上下文環境只須要不多的開銷,但若是當前正在運行的進程轉換成另外一個狀態,則操做系統必須使其環境發生實質的變化。
完整的切換過程以下:
1.保存處理器上下文環境
2.更新當前處於運行態的進程控制塊,將其狀態改變到另外一狀態。
3.將進程移動至相關隊列
4.選擇另外一個進程
5.更新所選擇進程的控制塊,將其狀態變成運行態。
6.更新內存管理的數據結構
7.恢復被選擇進程的處理器狀態。