進程
一個進程就是一個正在進行的任務(wù),計算機可以同時做很多任務(wù)姜盈,啟動多個進程,像個人電腦上同時開著瀏覽器瀏覽網(wǎng)面哟旗,開著音樂播放器聽音樂贩据,瀏覽器和播放器就是兩個不同的進程栋操。
一個CPU同一時間只能運行一個進程,多個進程同時運行只是看起來同運行饱亮,因為CPU會在多個進程間切換矾芙,每個進程運行幾十或幾百毫秒,看起來像同時在運行一樣〗希現(xiàn)在的多核CPU可以同時運行多個進行剔宪,但在每一個核上同時也只能運行一個進行。
進程模型
在進程模型中壹无,計算機上所有可運行的軟件葱绒,通常也包括系統(tǒng),被組織成若干順序進程斗锭,簡稱進程(process)地淀。一個進程就是一個正在執(zhí)行程序的實例,包括程序計數(shù)器岖是、寄存器和變量的當(dāng)前值帮毁。從概念上說,每個進程擁有它自己的虛擬CPU豺撑。當(dāng)前烈疚,實際上真正的CPU在各進程之間來回切換。
在一臺多道程序計算機的內(nèi)存中有4道程序聪轿。這4道程序被抽象為4個各自擁有自己控制流程(即第個程序自己的邏輯程序計數(shù)器)的進程爷肝,并且每個程序都獨立的運行。當(dāng)然陆错,實際上只有一個物理程序計數(shù)器灯抛,所以在每個程序運行時,它的邏輯程序計數(shù)器被裝入實際的程序計數(shù)器中危号。當(dāng)該程序執(zhí)行結(jié)束(或暫停執(zhí)行)時牧愁,物理程序計算器被保存在內(nèi)存中該進程的邏輯程序計算數(shù)器中。
進程創(chuàng)建
有以下4種主要事件會導(dǎo)致進程創(chuàng)建:
- 系統(tǒng)初始化
- 正在運行的程序執(zhí)行一個創(chuàng)建進程的系統(tǒng)調(diào)用
- 用戶請求創(chuàng)建一個新進程
- 一個批處理作業(yè)的初始化
啟動操作系統(tǒng)時外莲,通常會創(chuàng)建若干個進程猪半,其中有些是前臺進程,也就是同用戶交互并且替他們完成工作的那些進程偷线。其他的是后臺進程磨确,這些進程與特定的用戶沒有關(guān)系,相反卻具有某些專門的功能声邦。例如乏奥,郵件客戶端,在后臺運行定期查詢是否有新郵件亥曹。這些后臺進程稱為守護進程(daemon)邓了。在 Linux 中使用 ps 命令可以列出正在運行的進程恨诱,在 Windows 中可以使用任務(wù)管理器查看。
除了在啟動階段創(chuàng)建新的進程之外骗炉,新的進程也可以以后創(chuàng)建照宝。一個正在運行的進程經(jīng)常發(fā)出系統(tǒng)調(diào)用,以便創(chuàng)建一個或多個新的進程協(xié)助其工作句葵。在所從事的工作可以容易地劃分成若干相關(guān)的但沒有相互作用的進程時厕鹃,創(chuàng)建新的進程特別有效果。例如乍丈,如果有大量的數(shù)據(jù)要通過網(wǎng)絡(luò)調(diào)取并進行順序處理剂碴,那么創(chuàng)建一個進程取數(shù)據(jù),并把數(shù)據(jù)放入共享緩沖區(qū)中轻专,而讓第二個進程取走數(shù)據(jù)項并進行處理忆矛,應(yīng)該比較容易,在多處理機中请垛,讓第個進程在不同的CPU上運行會使整個作業(yè)運行行更快洪碳。
在交互式系統(tǒng)中,鍵入一個命令或者點擊一個圖標(biāo)就可以啟動一個程序叼屠。這兩個動作中的任何一個都會開始一個新進程。
最后一個創(chuàng)建進程的情形公在大型機的批處理系統(tǒng)中應(yīng)用绞铃。用戶在這種系統(tǒng)中提交批處理作業(yè)镜雨。在操作系統(tǒng)認(rèn)為有資源可以運行另一個作業(yè)時,他創(chuàng)建一個新的進程儿捧,并運行其輸入隊列中的下一個作業(yè)荚坞。
在 Unix 和 Windows 中進程創(chuàng)建之后,父進程和子進程有各自不同的地址空間菲盾。如果其中某個進程在其他地址空間中修改了一個字颓影,這個修改對其他進程而言是不可見的。在 Unix 中懒鉴,子進程初始地址空間是父進程的一個副本诡挂,但是這里涉及兩個不同的地址空間,不可寫的內(nèi)存區(qū)域是共享的临谱。某些 Unix 的實現(xiàn)使用程序正文在兩者間共享璃俗,因為他不能修改,或者悉默,子進程共享父進程的所有內(nèi)存城豁,但這種情況下內(nèi)存通過寫時復(fù)制(copy-on-write) 共享,這意味著一旦兩者之一想要修改部分內(nèi)存抄课,則這塊內(nèi)存首先被明確的復(fù)制唱星,以確保修改發(fā)生在私有區(qū)域雳旅。再次強調(diào),可寫的內(nèi)存是不可以共享的间聊。但是攒盈,對于一個新創(chuàng)建的進程而言,確實有可能共享其創(chuàng)建者的其他資源甸饱,諸如打開的文件等沦童。在 Windows 中,從一開始父進程的地址空間和子進程的地址空間就是不同的叹话。
進程終止
進程在創(chuàng)建之后偷遗,它開始運行,完成其工作驼壶。因為某原因進程終止退出氏豌,通常由下列條件引起的:
- 正常退出(自愿的)
- 出錯退出(自愿的)
- 嚴(yán)重錯誤(非自愿)
- 被其他進程殺死(非自愿)
多線進程是由于完成了它們的工作而終止。
有些進程在運行中因有些運行條件不滿足而退出
有些進程遇到的嚴(yán)重的錯誤热凹,不由自己控制的錯誤泵喘,如執(zhí)行了非法的指令、引用了不存在的內(nèi)存或除數(shù)為零等般妙。
最后一種纪铺,某個進程執(zhí)行一個系統(tǒng)調(diào)用通知操作殺死某個進程。Unix 中這個系統(tǒng)調(diào)用是 kill, 也有一個同名的命令
進程的層次結(jié)構(gòu)
某些系統(tǒng)中碟渺,當(dāng)進程創(chuàng)建了另一個進程后鲜锚,父進程和子進程就以某種形式繼續(xù)保持關(guān)聯(lián),進程只有一個父進程苫拍,但可以有多個子進程芜繁。
進程的狀態(tài)
盡管每個進程是一個獨立的實體,有其自己的程序計數(shù)器和內(nèi)部狀太绒极,但是進程之間經(jīng)常需要相互作用骏令。一個進程的輸出結(jié)果可能作為另一個進程的輸入。
shell 命令
cat chapter1 chapter2 chapter3|grep tree
中第一個進程運行 cat, 將三個文件連接并輸出垄提。第二個進程運行 grep, 它從輸入中選擇所有包含單詞 tree 的那些行榔袋。可能發(fā)生這種情況: grep 準(zhǔn)備就緒可以運行塔淤,但輸入還不有完成摘昌。于是必須阻塞 grep, 直到 輸入到來。
進程有三種狀態(tài):
- 運行態(tài)(該時刻進程實際占用 CPU)
- 就緒態(tài)(可運行高蜂,但因為其他進程正在運行而暫時停止)
- 阻塞態(tài)(除非某種外部事件發(fā)生聪黎,否則進程不能運行)
線程
在傳統(tǒng)操作系統(tǒng)中,第個進程有一個地址空間和一個控制線程。事實上稿饰,這幾乎就是進程的定義锦秒。不過,經(jīng)常存在在同一個地址空間中并行運行多個控制線程的情形喉镰,這些線程就像(差不多)分離的進程(共享地址空間外)旅择。
為什么需要線程
在許多應(yīng)用中同時發(fā)生著多種活動其中某活動隨著時間的推移會阻塞。通過將這些應(yīng)用程序分解成可以并行運行的多個順序線程侣姆,程序設(shè)計模型就變得更簡單生真。
同一個進程下的多個線程共享同一個地址空間和所有可用的數(shù)據(jù),這對于某些應(yīng)用是必須的捺宗,而進程之間是不共享的
線程比進程更輕量及柱蟀,所以他們比進程更容易(即更快)創(chuàng)建,也更容易撤銷蚜厉。在許多系統(tǒng)中长已,創(chuàng)建一個線程較創(chuàng)建一個進程要快10-100倍。在有大量線程需要動態(tài)和快速修改時昼牛,具有這一特性是很有用的术瓮。
多線程可以提高 CPU的利用率,在多CPU的系統(tǒng)中贰健,真正的并行有了實現(xiàn)的可能
經(jīng)典線程模型
進程模型基于兩種獨立的概念:資源分組處理與執(zhí)行胞四。有時將這兩種概念分開會更好,這就引入了 線程的概念伶椿。
理解進程的一個角度是撬讽,用某種方法把相關(guān)的資源集中在一起。進程有存放正文和數(shù)據(jù)以及其他資源的地址空間悬垃。這些資源中包括打開的文件、子進程甘苍、即將發(fā)生的定時器尝蠕、信號處理程序、賬號信息等载庭。把他們放到進程中可以更好的管理看彼。
另一個概念是,進程擁有一個執(zhí)行的線程囚聚,通常簡寫為線程(thread)靖榕。在線程中有一個程序計數(shù)器,用來記錄接著要執(zhí)行哪一條指令顽铸。線程擁有寄存器茁计,用來保存線程當(dāng)前的工作變量。線程還有一個堆棧谓松,用來記錄執(zhí)行歷史星压,其中每一幀保存了一個已調(diào)用 的但還沒有從中返回的過程践剂。盡管線程必須在某個進程中執(zhí)行,但是線程和它的進程是不同的概念娜膘,并且可以分別處理逊脯。進程用于把資源集中到一起,而線程則是在CPU上被調(diào)試執(zhí)行的實體
多線程與CPU利用率
要程序處理的快竣贪,要CPU都利用率提高军洼,提高CPU利率的常用方法是多線程。但也要分做的任務(wù)是CPU密集還是IO密集
計算密集型任務(wù)的特點是要進行大量的計算演怎,消耗CPU資源匕争,比如計算圓周率、對視頻進行高清解碼等等颤枪,全靠CPU的運算能力汗捡。這種計算密集型任務(wù)雖然也可以用多任務(wù)完成,但是任務(wù)越多畏纲,花在任務(wù)切換的時間就越多扇住,CPU執(zhí)行任務(wù)的效率就越低,所以盗胀,要最高效地利用CPU艘蹋,計算密集型任務(wù)同時進行的數(shù)量應(yīng)當(dāng)?shù)扔贑PU的核心數(shù)。
第二種任務(wù)的類型是IO密集型票灰,涉及到網(wǎng)絡(luò)女阀、磁盤IO的任務(wù)都是IO密集型任務(wù),這類任務(wù)的特點是CPU消耗很少屑迂,任務(wù)的大部分時間都在等待IO操作完成(因為IO的速度遠(yuǎn)遠(yuǎn)低于CPU和內(nèi)存的速度)浸策。對于IO密集型任務(wù),任務(wù)越多惹盼,CPU效率越高庸汗,但也有一個限度。常見的大部分任務(wù)都是IO密集型任務(wù)手报,比如Web應(yīng)用蚯舱。