本文原始地址: https://is.daryl.moe/2017/12/...
一個進程就是一個正在執行的程序實例,它包括程序計數器、寄存器以及變量的當前值。一個程序運行,它的邏輯計數器裝入 CPU 的程序計數器中;一個程序暫停,CPU 的程序計數器被保存在內存的邏輯程序計數器中,在下次運行前不佔用 CPU。網絡
要特別注意的是,進程並非在 CPU 中一直運行的,CPU 會在各進程之間來回切換,因此每一個進程執行的速度是不肯定的。因此,大多數進程並不受 CPU 多道程序設計或其它進程相對速度的影響。操作系統
有四種狀況會致使進程的建立,它們分別是系統初始化、正在運行的程序執行了建立進程的系統調用、用戶請求建立一個新進程、一個批處理做業的初始化。拿 Linux 爲例,Linux 啓動時的第一個進程是 0 號進程,它是全部進程的祖先。其次是 1 號進程,它是全部用戶進程的祖先。設計
咱們都知道 Nginx。當咱們啓動 Nginx 後,它一直在默默地監聽端口執行 WEB 服務,而咱們沒有感知。這一類進程,即是守護進程。指針
任何進程,均可以建立一個新的進程,這個進程即是子進程,執行的是 fork
系統調用。進程能夠 fork 子進程,子進程共享父進程的數據,可是,子進程對數據作的任何修改,對於父進程,都是不可見的。子進程的內存地址空間,是父進程的副本,是不一樣的地址空間。code
進程只能有一個父進程,可是一個進程能夠有多個子進程。在 UNIX 中,進程不能剝奪其子進程的繼承權。繼承
可寫的空間是不共享的,共享的空間是不可寫的。子進程能夠共享父進程的內存空間,可是要經過寫時複製共享。即在修改部份內存,先要明確地複製,以確保發生在私有的內存區域。生命週期
進程終止一般由下面的狀況引發,正常退出、出錯退出、嚴重錯誤、被其餘進程殺死。其中後面兩種狀況是非自願的。Linux 中自願終止進程能夠經過調用 exit
系統調用完成。進程
進程由三種狀態,運行、阻塞和就緒。內存
處在運行態的進程,在這個時刻實際佔用 CPU。get
處在就緒態的進程具有能夠運行條件,可是由於其它進程正在運行,而被操做系統暫停運行。
處在阻塞態的進程,因該進程調用了本地阻塞的系統調用,致使暫停運行。處在阻塞態的進程,不具有能夠運行的條件。除非外部某實踐發生,例如本地阻塞的調用完成,方可以轉換爲就緒態,等待操做系統調度。
操做系統維護這一個進程表,每個進程的詳細信息都保存在這張進程表中。包括程序計數器、堆棧指針、內存分配狀況、文件打開狀況、中斷向量等。
如前面所說,每一個進程都不是一直在 CPU 中運行地。其中就緒態和阻塞態是非運行狀態。當操做系統將正在運行的進程切換爲就緒態,或者進程由於調用了本地阻塞的系統調用而進入阻塞態時,其運行信息被保存在進程表中。當操做系統從新切換進程爲運行狀態時,將進程表中的信息恢復,就像進程沒有中斷同樣。
以 IO 爲例。當一個進程 A 調用了網絡 IO 的系統調用時,因爲該系統調用時阻塞的,因而操做系統將其切換爲阻塞態,而且將它的現場都保存在進程表中,並將此地址與中斷向量映射保存。而後,切換 B 進程。一段時間過去,此時多是 C 進程在 CPU 中運行,A 進程調用的 IO 完成了,則該硬件發生了一箇中斷。此時,操做系統將中斷正在運行的 C 進程,同時經過中斷向量找到進程表中的 A 進程的現場並恢復到 A 進程沒有中斷時的狀態,繼續運行。
一個進程,在其生命週期中,會被中斷數千次。每次中斷後恢復運行,都會恢復到未中斷時的狀態。
這裏只說說本身的理解。在工做的時候,偶然聽到同事這樣說,意思大體是這樣的:一個進程在網絡請求的時候,會影響其它進程的速度,致使其它進程變慢。這是不對的。一個進程,在遇到本地阻塞調用時,會中斷。這時,它的現場被保存在了進程表中,CPU 運行其它的進程。不存在一個進程會致使其它進程運行變慢的可能,只會存在調度由於進程數量變多而變慢的狀況,它們是不同的。
本文是做者閱讀《現代操做系統》的一些總結與理解,謹此記錄下來已被往後翻閱。同時,也分享給各位但願瞭解這些知識的同道者們。因爲做者水平有限,若有錯誤之處,望不吝賜教,謹表感謝。