進(jìn)程的定義
某種程度上,進(jìn)程代表程序的執(zhí)行過程,會消耗各種資源(CPU 內(nèi)存 IO等等)
一個具有一定獨(dú)立功能的程序在一個數(shù)據(jù)集合上的一次動態(tài)執(zhí)行過程。
進(jìn)程的組成
一個進(jìn)程應(yīng)該包括
- 程序的代碼
- 程序處理的數(shù)據(jù)
- 程序計(jì)數(shù)器中的值,表示下一條將運(yùn)行的指令
- 一組同樣的寄存器的當(dāng)前值,堆,棧
- 一組系統(tǒng)資源(比如打開的文件)
總之,進(jìn)程包含了正在運(yùn)行的一個程序的所有狀態(tài)信息。
進(jìn)程和程序的聯(lián)系 - 程序是產(chǎn)生進(jìn)程的基礎(chǔ)
- 程序的每次運(yùn)行構(gòu)成不同的進(jìn)程
- 進(jìn)程是程序功能的體現(xiàn)
- 通過多次執(zhí)行,一個程序可對應(yīng)多個進(jìn)程,通過調(diào)用關(guān)系,一個進(jìn)程可包括多個程序。
進(jìn)程和程序的區(qū)別 - 進(jìn)程是動態(tài)的,程序是靜態(tài)的;程序是有序代碼的集合,進(jìn)程是程序的執(zhí)行,進(jìn)程有核心態(tài)和用戶態(tài)(需要操作系統(tǒng)幫助完成某一功能 比如讀取文件,此時(shí)向操作系統(tǒng)發(fā)送請求,操作系統(tǒng)代表進(jìn)程執(zhí)行功能,此時(shí)處于核心態(tài))
- 進(jìn)程是暫時(shí)的,程序是永久的。進(jìn)程是一個狀態(tài)變化的過程,程序可長久保存
- 進(jìn)程和程序的組成不同:進(jìn)程的組成包括程序、數(shù)據(jù)和進(jìn)程控制塊
進(jìn)程與程序的關(guān)系類比
有一個計(jì)算機(jī)科學(xué)家,想親手給女兒做一個生日蛋糕。所以它就找了以本有關(guān)做蛋糕的食譜,買了一些原料,面粉、雞蛋、糖、香料等,然后邊看邊做。
食譜=程序;科學(xué)家=CPU;原料=數(shù)據(jù);做蛋糕=進(jìn)程
進(jìn)一步延展
這時(shí)小兒子跑進(jìn)來,說手被蜜蜂蟄了,科學(xué)家只好停下手中的活,他在食譜上做了個標(biāo)記,把狀態(tài)信息保存了起來。
然后又去找了一本醫(yī)療手冊,查到了相關(guān)的內(nèi)容,按照上面的指令一步步執(zhí)行。當(dāng)傷口處理完之后,又回到廚房從上次停下的位置繼續(xù)做蛋糕。
這就好比一個進(jìn)程執(zhí)行過程中,CPU要去執(zhí)行另一個進(jìn)程,那會記錄當(dāng)前進(jìn)程的狀態(tài)信息,當(dāng)回來繼續(xù)執(zhí)行該進(jìn)程的時(shí)候,會reload狀態(tài)信息,從上一次停止的地方開始執(zhí)行。
進(jìn)程的特點(diǎn)
動態(tài)性:可動態(tài)的創(chuàng)建、結(jié)束進(jìn)程
并發(fā)性:進(jìn)程可以被獨(dú)立調(diào)度并占用CPU運(yùn)行。
獨(dú)立性:不同進(jìn)程的工作不相互影響(操作系統(tǒng)給不同的進(jìn)程分配不同的頁表,保證每個進(jìn)程在獨(dú)立的內(nèi)存空間中運(yùn)行)
制約性:因訪問共享數(shù)據(jù)/資源或進(jìn)程間同步而產(chǎn)生制約。
程序=算法+數(shù)據(jù)結(jié)構(gòu)
描述進(jìn)程的數(shù)據(jù)結(jié)構(gòu):進(jìn)程控制塊(Process Control Block,PCB)
操作系統(tǒng)為每個進(jìn)程都維護(hù)了一個PCB,用來保存與該進(jìn)程有關(guān)的各種狀態(tài)信息。
進(jìn)程控制結(jié)構(gòu)
進(jìn)程控制塊:操作系統(tǒng)管理控制進(jìn)程運(yùn)行所用的信息集合
操作系統(tǒng)用PCB來描述進(jìn)程的基本情況以及運(yùn)行變化的過程
PCB是進(jìn)程存在的唯一標(biāo)識
進(jìn)程的創(chuàng)建:為該進(jìn)程生成一個PCB
進(jìn)程的終止:回收它的PCB
進(jìn)程的組織管理:通過對PCB的組織管理來實(shí)現(xiàn)
PCB含有3大類信息
(一)進(jìn)程標(biāo)識信息。入本進(jìn)程的標(biāo)識,本進(jìn)程的產(chǎn)生者標(biāo)識(父進(jìn)程標(biāo)識);用戶標(biāo)識
(二)處理機(jī)狀態(tài)信息保存區(qū)。保存進(jìn)行的運(yùn)行現(xiàn)場信息
- 用戶可見寄存器,用戶程序可以使用的數(shù)據(jù),地址等寄存器
- 控制和狀態(tài)寄存器,如程序計(jì)數(shù)器(PC),程序狀態(tài)字(PSW)
- 棧指針,過程調(diào)用/系統(tǒng)調(diào)用/中斷處理和返回時(shí)都需要用到它
(三)進(jìn)程控制信息 - 調(diào)度和狀態(tài)信息,用于操作系統(tǒng)調(diào)度進(jìn)程并占用處理機(jī)使用
- 進(jìn)程間通信,為支持進(jìn)程間的與通信相關(guān)的各種標(biāo)識,信號,信件等,這些信息存在接受方的進(jìn)程控制塊中。
- 存儲管理信息,包含有指向本進(jìn)程映像存儲空間的數(shù)據(jù)結(jié)構(gòu)
- 進(jìn)程所用資源,說明由進(jìn)程打開,使用的系統(tǒng)資源,如打開的文件
- 有關(guān)數(shù)據(jù)結(jié)構(gòu)連接信息,進(jìn)程可以連接到一個進(jìn)程隊(duì)列中,或連接到相關(guān)的其它進(jìn)程的PCB
PCB的組織方式:鏈表和索引表 - 鏈表:同一狀態(tài)的進(jìn)程其PCB成一鏈表,多個狀態(tài)對應(yīng)多個不同的鏈表。各狀態(tài)的進(jìn)程形成不同的鏈表:就緒鏈表,阻塞鏈表。
- 索引表:同一狀態(tài)的進(jìn)程歸入一個index表(由indx指向PCB),多個狀態(tài)對應(yīng)多個不同的index表-
進(jìn)程的生命周期
進(jìn)程的生命期管理:
進(jìn)程創(chuàng)建
引起進(jìn)程創(chuàng)建的3個主要事件:
- 系統(tǒng)初始化時(shí)
- 用戶請求創(chuàng)建一個新進(jìn)程
- 正在運(yùn)行的進(jìn)程執(zhí)行了創(chuàng)建進(jìn)程的系統(tǒng)調(diào)用
進(jìn)程運(yùn)行
內(nèi)核選擇一個就緒的進(jìn)程,讓它占用處理機(jī)執(zhí)行
進(jìn)程等待
- 請求并等待系統(tǒng)服務(wù),無法馬上完成
- 啟動某種操作,無法馬上完成
- 需要的數(shù)據(jù)沒有到達(dá)。
進(jìn)程只能自己阻塞自己,因?yàn)橹挥羞M(jìn)程自身才能知道何時(shí)需要等待某種事件的發(fā)生。
進(jìn)程喚醒
喚醒進(jìn)程的原因 - 被阻塞進(jìn)程需要的資源可被滿足
- 被阻塞進(jìn)程等待的事件達(dá)到
- 將該進(jìn)程的PCB插入到就緒隊(duì)列
進(jìn)程只能被別的進(jìn)程或操作系統(tǒng)喚醒。
進(jìn)程結(jié)束 - 正常退出(自愿的)
- 錯誤退出(自愿的)
- 致命錯誤(強(qiáng)制性的)
- 被其它進(jìn)程所殺(強(qiáng)制性的)
進(jìn)程狀態(tài)變化模型
三種基本狀態(tài):
運(yùn)行狀態(tài)(Running):當(dāng)一個進(jìn)程正在處理機(jī)上運(yùn)行
就緒狀態(tài)(Ready):一個進(jìn)程獲得了除處理機(jī)之外的一切所需資源,一旦得到處理機(jī)即可運(yùn)行
等待狀態(tài)(又稱阻塞狀態(tài) Blocked):一個進(jìn)程正在等待某一事件而暫停運(yùn)行時(shí),如等待某資源,等待輸入/輸出完成。

進(jìn)程的其它狀態(tài):
創(chuàng)建狀態(tài)(New):一個進(jìn)程正在被創(chuàng)建,還沒有被轉(zhuǎn)到就緒狀態(tài)之前的狀態(tài)
結(jié)束狀態(tài)(Exit):一個進(jìn)程正在從系統(tǒng)中消失時(shí)的狀態(tài),這是因?yàn)檫M(jìn)程結(jié)束或由于其它原因造成。

進(jìn)程掛起
進(jìn)程在掛起狀態(tài)時(shí),意味著進(jìn)程沒有占用內(nèi)存空間。處在掛起狀態(tài)的進(jìn)程映像在磁盤上。
- 阻塞掛起狀態(tài)(Blocked-suspend):進(jìn)程在外存并等待某事件的出現(xiàn)。
- 就緒掛起狀態(tài)(Ready-suspend):進(jìn)程在外存,但只要進(jìn)入內(nèi)存,即可運(yùn)行。
解掛/激活(Activie):把一個進(jìn)程從外存轉(zhuǎn)到內(nèi)存,可能有以下幾種情況
- 就緒掛起到就緒:沒有就緒進(jìn)程或者掛起就緒進(jìn)程優(yōu)先級高于就緒進(jìn)程時(shí),會進(jìn)行這種轉(zhuǎn)換。
- 阻塞掛起到阻塞:當(dāng)一個進(jìn)程釋放足夠內(nèi)存時(shí),系統(tǒng)會把一個高優(yōu)先級阻塞掛起(系統(tǒng)認(rèn)為會很快出現(xiàn)所等待的事件)進(jìn)程轉(zhuǎn)換為阻塞進(jìn)程。
問題:OS怎么通過PCB和定義的進(jìn)程狀態(tài)來管理PCB,幫助完成進(jìn)程的調(diào)度過程?
狀態(tài)隊(duì)列
- 由操作系統(tǒng)來維護(hù)一組隊(duì)列,用來表示系統(tǒng)當(dāng)中所有進(jìn)程的當(dāng)前狀態(tài)
- 不同的狀態(tài)分別用不同的隊(duì)列來表示(就緒隊(duì)列、各種類型的阻塞隊(duì)列)
- 每個進(jìn)程的PCB都根據(jù)它的狀態(tài)加入到相應(yīng)的隊(duì)列中,當(dāng)一個進(jìn)程的狀態(tài)發(fā)生變化時(shí),它的PCB從一個狀態(tài)隊(duì)列中脫離出來,加入到另一個隊(duì)列。
上下文切換
停止當(dāng)前運(yùn)行進(jìn)程(從運(yùn)行狀態(tài)改變成其它狀態(tài))并且調(diào)度其它進(jìn)程(轉(zhuǎn)變?yōu)檫\(yùn)行狀態(tài))


創(chuàng)建進(jìn)程
Unix進(jìn)程創(chuàng)建系統(tǒng)調(diào)用:fork/exec
fork()把一個進(jìn)程復(fù)制成二個進(jìn)程
parent(old PID), child(new PID)
exec()用新程序來重寫當(dāng)前進(jìn)程
PID沒有改變



等待和終止進(jìn)程
wait()系統(tǒng)調(diào)用是被父進(jìn)程用來等待子進(jìn)程的結(jié)束


子進(jìn)程執(zhí)行了exit(),但父進(jìn)程已經(jīng)先于子進(jìn)程死亡,此時(shí)沒有父進(jìn)程在等待它執(zhí)行wait(),此時(shí)子進(jìn)程就交給祖宗進(jìn)程(init進(jìn)程、root進(jìn)程)管理,會定期掃描隊(duì)列中是否有僵尸線程,如果有 會進(jìn)行回收。
