進程是計算機中一個很是重要的概念,在整個計算機發展歷史中,操做系統中程序運行機制的演變按順序大體能夠分爲:git
從單道程序演化爲多道程序就是CPU的高速與I/O的低速有着顯著矛盾,所以引入了多道程序做爲解決。舉一個例子,在單道程序中,假若I/O沒有完成,那麼CPU就會一直處於空閒狀態。可是在多道程序中,當某程序在佔用CPU的時候,其他程序能夠開始進行I/O請求,互不干擾,這樣就減小了在I/O中CPU的空閒。當某個程序釋放CPU後,下一程序繼續佔用CPU。github
在多道程序中,常常會有這種狀況,例如某程序須要監測輸入值,那麼,該程序就會委託I/O系統去取值,那麼在取值完成前,該程序並不須要佔用CPU,那麼程序會因爲I/O阻塞主動放棄CPU,而且進入執行隊列尾部,此時CPU會按出隊列的順序依次分配。c#
多道程序的狀態:
網絡
多道程序的調度
多線程
進程就是在程序中加入一些描述程序狀態的塊(PCB)併發
從多道程序演化爲進程的過程當中是經過提升併發性,從而進一步的提升CPU的利用率。事實上也就是在多道程序死板的調度機制中靈活的進行控制程序運行的順序等。實現的功能即是PCB的監控。異步
進程的狀態:
ide
進程的調度:
函數
在進程之下,咱們引入了線程。在說線程以前,咱們引入那麼一個問題,假定你製做了一個即時通信的程序,若是你只是用一個進程去控制程序運行,會發生什麼?事實上這裏發生的事情你有時候能夠在一些小廠商作出的低劣遊戲中發現這一問題。咱們在有些製做很差、歷史久遠或者代碼質量差的遊戲中,常常能發現,一旦網卡了,整個遊戲甚至都會卡頓甚至無響應,遊戲的渲染也受到了很大的影響。有時候是由於網絡一直在嘗試發包致使,可是更多時候是由於進程調度問題。但是爲何網絡是基於外部的,卻能夠影響內部的引擎渲染之類的功能呢?緣由就是咱們以前講過,請求網絡是一個明顯的I/O過程,假設網絡很差,那麼咱們的程序一直處於I/O阻塞的狀態下,從而放棄CPU,那麼咱們渲染的代碼也會遲遲得不到運行。會到咱們以前的問題,假設你只是用一個進程去製做了即時通信軟件,一旦網絡丟包之類的網絡故障發生時,你的程序很容易卡頓。ui
說了那麼多,咱們應該如何去解決這個問題?很天然的咱們會想到使用多進程去製做一個軟件,那麼其中一個進程發生阻塞的時候,咱們其他的進程會繼續佔用CPU,則總體運行並不會受太大影響。可是這種方法須要佔用大量的時空,由於進程的調度是依賴PCB以及PCB的監控程序,進程切換過程當中,上下文切換也會致使PCB狀態切換,須要花費大量的時間進行查詢、修改等操做,而且內存棧的使用也會過於頻繁致使空間消耗,而且在操做系統中,PCB的數量是有限的,所以使用多進程並非一個號的方法。
這裏咱們就引出多線程的方法,進程就成爲了線程的一個容器,且進程和線程能夠同時存在,線程幾乎不佔用多少空間,總體也比進程小的多,那麼對線程的調度開銷就會遠比進程小得多。進程的數量也減小了,那麼總體系統的壓力也小了。
一般咱們只考慮爲PCB+程序或PCB+指令段+數據段。這裏涉及到的指令段和數據段是什麼呢?
指令段就是具體的操做邏輯,而數據段就是存儲的具體數據值,他們一般都存儲在棧上。例若有一段代碼:
public int Add() { return 3+4; }
這段代碼在進程中會存儲函數指針,也就是程序的具體內存位置;3和4將會做爲數據段存儲在獨立的堆棧中,而 ‘+’會存儲在指令段中。
進程的組成
對於一個進程或程序須要運行,如下三個東西是必不可少的:
進程的狀態:
在狀態轉變的時候,一般就是要實施如下三步:
若是個人文章幫助了你,請給我一個三連和star。