目錄
??專欄導(dǎo)讀
??什么是進(jìn)程
?什么是PCB??
??查看進(jìn)程?
??如何通過系統(tǒng)調(diào)用查看進(jìn)程PID
??fork
??認(rèn)識(shí)進(jìn)程狀態(tài)
??查看進(jìn)程狀態(tài)?
??R狀態(tài)
??例如:
??S狀態(tài)?
??D狀態(tài)?
??T狀態(tài)
??t狀態(tài):
??X狀態(tài)?
??Z狀態(tài)
?僵尸進(jìn)程
?僵尸進(jìn)程的危害?
??孤兒進(jìn)程
??專欄導(dǎo)讀
??作者簡介:日出等日落,在讀本科生一枚,致力于 C/C++、Linux?學(xué)習(xí)。
??本文收錄于 Linux系列,本專欄主要內(nèi)容為 C++ 初階、C++ 進(jìn)階、STL?詳解等,持續(xù)更新!
??相關(guān)專欄推薦:C語言系列 、Linux系列 、數(shù)據(jù)結(jié)構(gòu)與算法
??什么是進(jìn)程
有小伙伴就會(huì)問了,什么是進(jìn)程呢?
進(jìn)程=內(nèi)核關(guān)于進(jìn)程的相關(guān)數(shù)據(jù)結(jié)構(gòu)+當(dāng)前代碼的內(nèi)容和數(shù)據(jù)
什么是進(jìn)程?
早期的計(jì)算機(jī)一次只能執(zhí)行一個(gè)程序,這種程序完全控制系統(tǒng),并且訪問所有系統(tǒng)資源。到了現(xiàn)代,計(jì)算機(jī)系統(tǒng)允許加載多個(gè)程序到內(nèi)存,以便于并發(fā)執(zhí)行。這就要求操作系統(tǒng)對(duì)各種程序提供更嚴(yán)格的控制和更好地劃分和規(guī)劃。這些需求引發(fā)了進(jìn)程概念的產(chǎn)生,大白話來說,進(jìn)程就是正在執(zhí)行的程序,是現(xiàn)代分時(shí)操作系統(tǒng)的工作單元。
操作系統(tǒng)的復(fù)雜程度決定它可以為用戶帶來更好地體驗(yàn)感。雖然它主要關(guān)注的是執(zhí)行用戶程序,但是它也要顧及各種系統(tǒng)任務(wù)。因此系統(tǒng)會(huì)由一組進(jìn)程組成,操作系統(tǒng)進(jìn)程和用戶進(jìn)程;操作系統(tǒng)進(jìn)程執(zhí)行系統(tǒng)代碼,而用戶進(jìn)程執(zhí)行用戶代碼。
通過 CPU 的多路復(fù)用,所有這些進(jìn)程可以并發(fā)執(zhí)行。通過在進(jìn)程之間切換 CPU,操作系統(tǒng)能使計(jì)算機(jī)更為高效。前面說,進(jìn)程是執(zhí)行的程序,這是一種非正式的說法。進(jìn)程不只是程序代碼(文本段或代碼段),通常還包含以下內(nèi)容:
- 當(dāng)前活動(dòng),如程序計(jì)數(shù)器的值和處理器寄存器的內(nèi)容等。
- 進(jìn)程堆棧(包括臨時(shí)數(shù)據(jù),如函數(shù)參數(shù)、返回地址和局部變量)和數(shù)據(jù)段(包括全局變量)。
- 堆,這是在進(jìn)程運(yùn)行時(shí)動(dòng)態(tài)分配的內(nèi)存。
?什么是PCB??
從操作系統(tǒng)理解進(jìn)程概念-------先描述,后組織
為了使參與并發(fā)執(zhí)行的程序能獨(dú)立的運(yùn)行,必須為之配置一個(gè)專門的數(shù)據(jù)結(jié)構(gòu)-----task_struct,稱為進(jìn)程控制塊(PCB)。進(jìn)程信息被放在一個(gè)叫做進(jìn)程控制塊的數(shù)據(jù)結(jié)構(gòu)中,可以理解為進(jìn)程屬性的集合。
系統(tǒng)利用PCB來描述進(jìn)程的基本情況和運(yùn)行狀態(tài),進(jìn)而控制和管理進(jìn)程(也就是組織)進(jìn)程。 相應(yīng)地,由程序段、相關(guān)數(shù)據(jù)段和PCB三部分構(gòu)成了進(jìn)程映像(進(jìn)程實(shí)體)。所謂創(chuàng)建進(jìn)程,實(shí)質(zhì)上是創(chuàng)建進(jìn)程映像中的PCB;而撤銷進(jìn)程,實(shí)質(zhì)上是撤銷進(jìn)程的PCB。值得注意的是,進(jìn)程映像是靜態(tài)的,進(jìn)程則是動(dòng)態(tài)的。
進(jìn)程的唯一標(biāo)志—PCB
綜上所述,進(jìn)程的定義大體分為以下幾點(diǎn)
- 進(jìn)程是程序的一次執(zhí)行
- 進(jìn)程是一個(gè)程序及其數(shù)據(jù)在處理機(jī)上順序執(zhí)行時(shí)所發(fā)生的活動(dòng)
- 進(jìn)程是具有獨(dú)立功能的程序在一個(gè)數(shù)據(jù)集合上運(yùn)行過程,它是系統(tǒng)進(jìn)行資源分配和調(diào)度的一個(gè)獨(dú)立單位
進(jìn)程的特征
- 進(jìn)程是由多程序的并發(fā)執(zhí)行而引出的,它和程序是兩個(gè)截然不同的概念。進(jìn)程的基本特征是對(duì)比單個(gè)程序的順序執(zhí)行提出的,也是對(duì)進(jìn)程管理提出的基本要求。
動(dòng)態(tài)性:進(jìn)程是程序的一次執(zhí)行,它有著創(chuàng)建、活動(dòng)、暫停、終止等過程,具有一定的生命周期,是動(dòng)態(tài)地產(chǎn)生、變化和消亡的。動(dòng)態(tài)性是進(jìn)程最基本的特征。
并發(fā)性:指多個(gè)進(jìn)程實(shí)體,同存于內(nèi)存中,能在一段時(shí)間內(nèi)同時(shí)運(yùn)行,并發(fā)性是進(jìn)程的重要特征,同時(shí)也是操作系統(tǒng)的重要特征。引入進(jìn)程的目的就是為了使程序能與其他進(jìn)程 的程序并發(fā)執(zhí)行,以提高資源利用率。
獨(dú)立性:指進(jìn)程實(shí)體是一個(gè)能獨(dú)立運(yùn)行、獨(dú)立獲得資源和獨(dú)立接受調(diào)度的基本單位。凡未建立PCB的程序都不能作為一個(gè)獨(dú)立的單位參與運(yùn)行。
異步性:由于進(jìn)程的相互制約,使進(jìn)程具有執(zhí)行的間斷性,即進(jìn)程按各自獨(dú)立的、 不可預(yù)知的速度向前推進(jìn)。異步性會(huì)導(dǎo)致執(zhí)行結(jié)果的不可再現(xiàn)性,為此,在操作系統(tǒng)中必須 配置相應(yīng)的進(jìn)程同步機(jī)制。
結(jié)構(gòu)性:每個(gè)進(jìn)程都配置一個(gè)PCB對(duì)其進(jìn)行描述。從結(jié)構(gòu)上看,進(jìn)程實(shí)體是由程序段、數(shù)據(jù)段和進(jìn)程控制段三部分組成的。
進(jìn)程的狀態(tài)和轉(zhuǎn)換
task_ struct內(nèi)容分類
- 標(biāo)示符: 描述本進(jìn)程的唯一標(biāo)示符,用來區(qū)別其他進(jìn)程。
- 狀態(tài): 任務(wù)狀態(tài),退出代碼,退出信號(hào)等。
- 優(yōu)先級(jí): 相對(duì)于其他進(jìn)程的優(yōu)先級(jí)。
- 程序計(jì)數(shù)器: 程序中即將被執(zhí)行的下一條指令的地址。
- 內(nèi)存指針: 包括程序代碼和進(jìn)程相關(guān)數(shù)據(jù)的指針,還有和其他進(jìn)程共享的內(nèi)存塊的指針
- 上下文數(shù)據(jù): 進(jìn)程執(zhí)行時(shí)處理器的寄存器中的數(shù)據(jù)[休學(xué)例子,要加圖CPU,寄存器]。
- I/O狀態(tài)信息: 包括顯示的I/O請(qǐng)求,分配給進(jìn)程的I/O設(shè)備和被進(jìn)程使用的文件列表。
- 記賬信息: 可能包括處理器時(shí)間總和,使用的時(shí)鐘數(shù)總和,時(shí)間限制,記賬號(hào)等。
- 其他信息
??查看進(jìn)程?
#include<stdio.h>
int main()
{
while(1)
{
printf("我是一個(gè)進(jìn)程\n");
sleep(1);
}
return 0;
}
- 這是一個(gè)簡單的進(jìn)程(myprocess)
ps axj | head -1 && ps axj | grep myprocess | grep -v grep
- 這是查看進(jìn)程的指令!
??如何通過系統(tǒng)調(diào)用查看進(jìn)程PID
我們還可以用系統(tǒng)調(diào)用
getpid()
獲取當(dāng)前進(jìn)程的pid
,getppid()
獲取當(dāng)前進(jìn)程的父進(jìn)程的PID
。首先通過
man
手冊查詢這兩個(gè)函數(shù)如何使用:$ man getpid
運(yùn)行截圖:?
?注意,返回值類型未pid_t
其實(shí)就是size_t
。通過一下代碼進(jìn)行測試:
#include<stdio.h>
#include<sys/types.h>
int main()
{
while(1)
{
printf("我是一個(gè)進(jìn)程,我的PID是:%d,我的父進(jìn)程是:%d\n",getpid(),getppid());
sleep(1);
}
return 0;
}
運(yùn)行截圖:?
??fork
首先我們通過man
手冊認(rèn)識(shí)一下fork
;
$ man fork
運(yùn)行截圖:?
?簡單說明就是fork
用來創(chuàng)建子進(jìn)程,在父進(jìn)程中,fork
的返回值為子進(jìn)程的PID
;在子進(jìn)程中返回值為0。
#include<stdio.h>
#include<sys/types.h>
int main()
{
printf("fork調(diào)用之前的內(nèi)容.....\n");
fork();
printf("fork調(diào)用之后的內(nèi)容.....\n");
return 0;
}
運(yùn)行截圖:?
我們可以看出這里
fork
調(diào)用之后的內(nèi)容打印了兩遍。原因是當(dāng)調(diào)用fork
之后,子進(jìn)程被創(chuàng)建,父進(jìn)程與子進(jìn)程同時(shí)在運(yùn)行,于是父進(jìn)程打印了一遍fork
調(diào)用后的內(nèi)容,子進(jìn)程也打印了一遍fork
調(diào)用后的內(nèi)容。
fork
的功能很強(qiáng)大,我們一般需要與if
配合使用進(jìn)行分流
。還記得上面提到的fork
的返回值嗎?子進(jìn)程返回值為0
,父進(jìn)程返回值為子進(jìn)程PID
,可以此作為分流的依據(jù)。例如:
#include<stdio.h>
#include<sys/types.h>
int main()
{
pid_t ret = fork();
if(ret==0)
{
// 子進(jìn)程
while(1)
{
printf("我是子進(jìn)程,我的PID是:%d,我的父進(jìn)程是:%d\n",getpid(),getppid());
sleep(1);
}
}
else
{
// 父進(jìn)程
while(1)
{
printf("我是父進(jìn)程,我的PID是:%d,我的父進(jìn)程是:%d\n",getpid(),getppid());
sleep(1);
}
}
return 0;
}
運(yùn)行截圖:
此刻父子進(jìn)程都在運(yùn)行。那么問題來了——
- 請(qǐng)問為什么此時(shí)
if
與else
竟然能夠同時(shí)執(zhí)行?也就是fork
為什么會(huì)有兩個(gè)返回值
?
?進(jìn)程間是互相獨(dú)立的
例如qq與微信同時(shí)運(yùn)行,兩個(gè)并無關(guān)聯(lián),互不影響。
我們知道進(jìn)程=內(nèi)核數(shù)據(jù)結(jié)構(gòu)(PCB)+代碼和數(shù)據(jù)。當(dāng)子進(jìn)程創(chuàng)建時(shí),操作系統(tǒng)會(huì)為子進(jìn)程創(chuàng)建一個(gè)PCB記錄子進(jìn)程的狀態(tài)信息等。同時(shí)子進(jìn)程會(huì)與父進(jìn)程共同使用一份代碼和數(shù)據(jù),若有任意一個(gè)執(zhí)行流(只父子進(jìn)程)修改數(shù)據(jù)時(shí),操作系統(tǒng)會(huì)為該進(jìn)程將代碼和數(shù)據(jù)拷貝一份,再進(jìn)行修改,此動(dòng)作我們稱之為寫時(shí)拷貝,寫時(shí)拷貝同樣為非常重要的知識(shí)。
最后,因?yàn)檫M(jìn)程具有獨(dú)立性,同樣父子進(jìn)程也具有獨(dú)立性,且由于寫時(shí)拷貝的存在,父進(jìn)程中調(diào)用fork會(huì)返回子進(jìn)程的PID,所以else執(zhí)行了,這是父進(jìn)程的行為;子進(jìn)程中會(huì)fork會(huì)返回0,所以if執(zhí)行了,這是子進(jìn)程的行為。父子進(jìn)程互不影響
??認(rèn)識(shí)進(jìn)程狀態(tài)
進(jìn)程在其生命周期內(nèi),由于系統(tǒng)中各進(jìn)程之間的相互制約關(guān)系及系統(tǒng)的運(yùn)行環(huán)境的變化,使得進(jìn)程的狀態(tài)也在不斷地發(fā)生變化(一個(gè)進(jìn)程會(huì)經(jīng)歷若干種不同狀態(tài))。通常進(jìn)程有以下五種狀態(tài),前三種是進(jìn)程的基本狀態(tài)。
- 運(yùn)行狀態(tài):進(jìn)程正在處理機(jī)上運(yùn)行。在單處理機(jī)環(huán)境下,每一時(shí)刻最多只有一個(gè)進(jìn)程處于運(yùn)行狀態(tài)。
- 就緒狀態(tài):進(jìn)程已處于準(zhǔn)備運(yùn)行的狀態(tài),即進(jìn)程獲得了除處理機(jī)之外的一切所需資源,一旦得到處理機(jī)即可運(yùn)行。
- 阻塞狀態(tài):又稱等待狀態(tài):進(jìn)程正在等待某一事件而暫停運(yùn)行,如等待某資源為可用(不包括處理機(jī))或等待輸入/輸出完成。即使處理機(jī)空閑,該進(jìn)程也不能運(yùn)行。
- 創(chuàng)建狀態(tài):進(jìn)程正在被創(chuàng)建,尚未轉(zhuǎn)到就緒狀態(tài)。創(chuàng)建進(jìn)程通常需要多個(gè)步驟:首先申請(qǐng)一個(gè)空白的PCB,并向PCB中填寫一些控制和管理進(jìn)程的信息;然后由系統(tǒng)為該進(jìn)程分 配運(yùn)行時(shí)所必需的資源;最后把該進(jìn)程轉(zhuǎn)入到就緒狀態(tài)。
- 結(jié)束狀態(tài):進(jìn)程正從系統(tǒng)中消失,這可能是進(jìn)程正常結(jié)束或其他原因中斷退出運(yùn)行。當(dāng)進(jìn)程需要結(jié)束運(yùn)行時(shí),系統(tǒng)首先必須置該進(jìn)程為結(jié)束狀態(tài),然后再進(jìn)一步處理資源釋放和 回收等工作。
Linux中進(jìn)程狀態(tài)一般有:
- R(運(yùn)行狀態(tài)):并不意外著真正的在運(yùn)行(指正在被CPU調(diào)度);
- S(休眠狀態(tài)):進(jìn)程在等待獲取某種資源,此狀態(tài)還被稱為可中斷休眠;
- D(磁盤休眠狀態(tài)):在這個(gè)狀態(tài)的進(jìn)程也是在休眠,但是不可被中斷,因此又稱過該狀態(tài)為不可中斷休眠;
- T(暫停狀態(tài)):可以通過發(fā)送 SIGSTOP 信號(hào)給進(jìn)程來停止進(jìn)程。這個(gè)被暫停的進(jìn)程可以通過發(fā)送 SIGCONT 信號(hào)讓進(jìn)程繼續(xù)運(yùn)行。
- X(死亡狀態(tài)):這個(gè)狀態(tài)只是一個(gè)返回狀態(tài),你不會(huì)在任務(wù)列表里看到這個(gè)狀態(tài);
- Z(僵尸狀態(tài)):當(dāng)一個(gè)子進(jìn)程沒有被父進(jìn)程“回收”,該進(jìn)程就會(huì)處于僵尸狀態(tài);
?
??查看進(jìn)程狀態(tài)?
指令:
ps axj | head -n1 && ps axj | grep myprocess | grep -v grep
??R狀態(tài)
當(dāng)你在電腦上同時(shí)運(yùn)行很多程序,例如你敲代碼的時(shí)候,還聽著某個(gè)軟件播放的歌曲,或者在瀏覽器之間來回切換。請(qǐng)問此時(shí)這些所有的應(yīng)用都在CPU運(yùn)行嗎?
答案是,并不是這樣的。
在CPU進(jìn)行工作的時(shí)候,會(huì)存在一個(gè)進(jìn)程運(yùn)行的隊(duì)列。隊(duì)列維護(hù)的內(nèi)容是一個(gè)個(gè)task_struct結(jié)構(gòu)體的指針。在該隊(duì)列中維護(hù)的進(jìn)程都處于R狀態(tài),且等著被CPU所調(diào)度。
??例如:
根據(jù)上圖,問題來了,為什么在該程序執(zhí)行時(shí),并沒有看到所謂的R狀態(tài)呢?
原因是由于CPU運(yùn)算速度太快了,我們基本很難看到R狀態(tài)。該進(jìn)程死循環(huán)的在屏幕上打印。我們都知道此時(shí)的屏幕是一種外設(shè),而CPU的計(jì)算速度相比較外設(shè)的訪問速度根本不在一個(gè)量級(jí)。所以,該進(jìn)程死循環(huán)的在屏幕上打印內(nèi)容,有99.9%的時(shí)間都在訪問外設(shè),剩下的時(shí)間是CPU在做計(jì)算。在進(jìn)程訪問外設(shè)的時(shí)候,CPU并不會(huì)傻傻的原地等待,而是轉(zhuǎn)頭卻做別的事,當(dāng)該進(jìn)程訪問外設(shè)成功后,CPU再對(duì)它進(jìn)行調(diào)度。
那么有什么辦法等看到R
狀態(tài)呢?我們將上面的代碼略作修改:
#include<stdio.h>
#include<unistd.h>
int main()
{
while(1)
{
//printf("hello myprocess\n");
}
return 0;
}
?運(yùn)行截圖:
?如上圖所示,當(dāng)我們不再訪問外設(shè),而是只不停地做重復(fù)的運(yùn)算,此時(shí)CPU
會(huì)一直被調(diào)度,就能看到R
狀態(tài)了。
??S狀態(tài)?
S狀態(tài)稱為休眠狀態(tài)。休眠狀態(tài)本質(zhì)是一種阻塞。
阻塞:進(jìn)程因?yàn)榈却撤N資源就緒而表現(xiàn)出的不推進(jìn)的狀態(tài)。
例如,當(dāng)一個(gè)進(jìn)程運(yùn)行到一半,需要從磁盤上獲取很大的一塊數(shù)據(jù),那么就要花費(fèi)較久的時(shí)間。此時(shí)OS的處理方式是,讓該進(jìn)程繼續(xù)等待它要的數(shù)據(jù),但是要求你不能在等待資源的時(shí)候還占用著CPU,于是該進(jìn)程就被OS安排到某個(gè)地方進(jìn)行等待,這時(shí)該進(jìn)程就處于S狀態(tài)。
運(yùn)行截圖:
如上圖所示,當(dāng)進(jìn)程等待用戶從鍵盤上輸入的數(shù)據(jù)時(shí),它就處于睡眠狀態(tài)
。?
??D狀態(tài)?
D狀態(tài)也是一種休眠狀態(tài),但是它又有個(gè)名字叫做磁盤休眠狀態(tài)或者不可中斷休眠。那么如何看待S狀態(tài)與D狀態(tài)的區(qū)別呢?
??T狀態(tài)
T
狀態(tài)稱為停止?fàn)顟B(tài),就是讓某個(gè)進(jìn)程暫停一下。
1 #include<stdio.h>
2 #include<unistd.h>
3
4 int main()
5 {
6 int count = 0;
7 while(1)
8 {
9 //printf("hello myprocess\n");
10 printf("我再運(yùn)行嗎??%d\n",count++);
11 sleep(1);
12 }
13 return 0;
14 }
當(dāng)程序開始運(yùn)行后,此時(shí)向進(jìn)程發(fā)送暫停的信號(hào):
$ kill -18 (進(jìn)程PID)
運(yùn)行截圖:?
此外,我們還可以發(fā)送繼續(xù)的信號(hào)讓該進(jìn)程繼續(xù)執(zhí)行:
$ kill -18 (進(jìn)程PID)
?運(yùn)行截圖:
?注意:
進(jìn)程繼續(xù)在運(yùn)行了。但是我們發(fā)現(xiàn)有一個(gè)地方好像和之前不一樣了,S后面是不是一直有一個(gè)+號(hào)來著?我們也不知道+是干嘛的,只知道他現(xiàn)在好像消失了。
“+” 代表在前臺(tái)運(yùn)行,沒有”+“表示在后臺(tái)運(yùn)行;
之前我們在終止一個(gè)程序時(shí),習(xí)慣使用Ctrl + c ,但是現(xiàn)在好像對(duì)于后臺(tái)在運(yùn)行的進(jìn)程失效了,此時(shí)我們需要掌握一條新的指令來”殺掉“進(jìn)程:
$ kill -9 (進(jìn)程PID)
??t狀態(tài):
?例如在調(diào)試時(shí),我們設(shè)置了幾個(gè)斷點(diǎn)。當(dāng)進(jìn)程在該斷點(diǎn)處停下來時(shí),該進(jìn)程就處于暫停狀態(tài)。
?
?
可以看見我們在第十行打了斷點(diǎn),此時(shí)觀看進(jìn)程狀態(tài):
?我們在調(diào)試中運(yùn)行一下:
觀看運(yùn)行狀態(tài):
??X狀態(tài)?
-
X
狀態(tài)為死亡狀態(tài)是一個(gè)瞬時(shí)狀態(tài)不易觀察,暫且認(rèn)為它不重要;
??Z狀態(tài)
-
Z
狀態(tài)被稱為僵尸狀態(tài)。顧名思義,一個(gè)進(jìn)程死了(退出了)但沒有”收尸“,就成了”僵尸“。具體一點(diǎn),當(dāng)一個(gè)進(jìn)程退出時(shí)如果它的父進(jìn)程沒有讀取到該進(jìn)程退出時(shí)返回的退出狀態(tài)碼,該進(jìn)程就會(huì)變成僵尸進(jìn)程。
?僵尸進(jìn)程
#include<stdio.h>
#include<unistd.h>
int main()
{
pid_t id = fork();
if(id == 0)
{
while(1)
{
printf("我是子進(jìn)程,我在運(yùn)行,pid:%d,ppid:%d\n",getpid(),getppid());
sleep(1);
}
}
else if(id > 0)
{
while(1)
{
printf("我是父進(jìn)程,我在運(yùn)行,pid:%d,ppid:%d\n",getpid(),getppid());
sleep(1);
}
}
return 0;
}
當(dāng)我們運(yùn)行程序后,能看到程序正常的在運(yùn)行;?
?此時(shí)當(dāng)我們執(zhí)行指令將子進(jìn)程”殺“掉,子進(jìn)程就會(huì)變成僵尸進(jìn)程;
$ kill -9 (子進(jìn)程PID)
其中我們能看到一個(gè)英文單詞——defunct
就是僵尸的意思。?
?僵尸進(jìn)程的危害?
- 維護(hù)退出狀態(tài)本身就是要用數(shù)據(jù)維護(hù),也屬于進(jìn)程基本信息,所以保存在
task_struct
(即PCB)中,換句話說,Z
狀態(tài)一直不退出,PCB
一直都要維護(hù)。 - 一個(gè)父進(jìn)程創(chuàng)建了很多子進(jìn)程,就是不回收,就會(huì)造成內(nèi)存資源的浪費(fèi)。因?yàn)閿?shù)據(jù)結(jié)構(gòu)對(duì)象本身就要占用內(nèi)存。
??孤兒進(jìn)程
所謂孤兒進(jìn)程,故名思義,和現(xiàn)實(shí)生活中的孤兒有點(diǎn)類似,當(dāng)一個(gè)進(jìn)程的父進(jìn)程結(jié)束時(shí),但是它自己還沒有結(jié)束,那么這個(gè)進(jìn)程將會(huì)成為孤兒進(jìn)程。
運(yùn)行該程序,我們使用kill命令”殺“掉父進(jìn)程,此時(shí)再來查看進(jìn)程信息:
如上圖所示,子進(jìn)程發(fā)生了兩個(gè)變化。一是子進(jìn)程的PPID
,二是子進(jìn)程變?yōu)樵诤笈_(tái)運(yùn)行了。?
當(dāng)子進(jìn)程的父進(jìn)程掛掉之后,子進(jìn)程會(huì)被1
號(hào)進(jìn)程領(lǐng)養(yǎng)。該進(jìn)程也被稱為孤兒進(jìn)程。
- 那么為什么要進(jìn)行領(lǐng)養(yǎng)呢?
原因是孤兒進(jìn)程會(huì)被init進(jìn)程(1號(hào)進(jìn)程)的進(jìn)程收養(yǎng),當(dāng)然在子進(jìn)程結(jié)束時(shí)也會(huì)由init進(jìn)程完成對(duì)它的狀態(tài)收集工作,因此一般來說,孤兒進(jìn)程并不會(huì)有什么危害.文章來源:http://www.zghlxwxcb.cn/news/detail-636267.html
?文章來源地址http://www.zghlxwxcb.cn/news/detail-636267.html
到了這里,關(guān)于【Linux】詳解進(jìn)程狀態(tài)之僵尸進(jìn)程——孤兒進(jìn)程的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!