国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

【Linux】詳解進(jìn)程狀態(tài)之僵尸進(jìn)程——孤兒進(jìn)程

這篇具有很好參考價(jià)值的文章主要介紹了【Linux】詳解進(jìn)程狀態(tài)之僵尸進(jìn)程——孤兒進(jìn)程。希望對(duì)大家有所幫助。如果存在錯(cuò)誤或未考慮完全的地方,請(qǐng)大家不吝賜教,您也可以點(diǎn)擊"舉報(bào)違法"按鈕提交疑問。

【Linux】詳解進(jìn)程狀態(tài)之僵尸進(jìn)程——孤兒進(jìn)程,Linux,linux

【Linux】詳解進(jìn)程狀態(tài)之僵尸進(jìn)程——孤兒進(jìn)程,Linux,linux

目錄

??專欄導(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)容:

  1. 當(dāng)前活動(dòng),如程序計(jì)數(shù)器的值和處理器寄存器的內(nèi)容等。
  2. 進(jìn)程堆棧(包括臨時(shí)數(shù)據(jù),如函數(shù)參數(shù)、返回地址和局部變量)和數(shù)據(jù)段(包括全局變量)。
  3. 堆,這是在進(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,寄存器]。
  • IO狀態(tài)信息: 包括顯示的I/O請(qǐng)求,分配給進(jìn)程的IO設(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)程的指令!

【Linux】詳解進(jìn)程狀態(tài)之僵尸進(jìn)程——孤兒進(jìn)程,Linux,linux

??如何通過系統(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)行截圖:?

【Linux】詳解進(jìn)程狀態(tài)之僵尸進(jìn)程——孤兒進(jìn)程,Linux,linux

?注意,返回值類型未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)行截圖:?

【Linux】詳解進(jìn)程狀態(tài)之僵尸進(jìn)程——孤兒進(jìn)程,Linux,linux

??fork

首先我們通過man手冊認(rèn)識(shí)一下fork;

$ man fork

運(yùn)行截圖:?

【Linux】詳解進(jìn)程狀態(tài)之僵尸進(jìn)程——孤兒進(jìn)程,Linux,linux

?簡單說明就是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)行截圖:?

【Linux】詳解進(jìn)程狀態(tài)之僵尸進(jìn)程——孤兒進(jìn)程,Linux,linux

我們可以看出這里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)行截圖:

【Linux】詳解進(jìn)程狀態(tài)之僵尸進(jìn)程——孤兒進(jìn)程,Linux,linux

此刻父子進(jìn)程都在運(yùn)行。那么問題來了——

  • 請(qǐng)問為什么此時(shí)ifelse竟然能夠同時(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)。

【Linux】詳解進(jìn)程狀態(tài)之僵尸進(jìn)程——孤兒進(jìn)程,Linux,linux

  • 運(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);

?【Linux】詳解進(jìn)程狀態(tài)之僵尸進(jìn)程——孤兒進(jìn)程,Linux,linux

??查看進(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)度。
【Linux】詳解進(jìn)程狀態(tài)之僵尸進(jìn)程——孤兒進(jìn)程,Linux,linux

??例如:

【Linux】詳解進(jìn)程狀態(tài)之僵尸進(jìn)程——孤兒進(jìn)程,Linux,linux

根據(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)行截圖:

【Linux】詳解進(jìn)程狀態(tài)之僵尸進(jìn)程——孤兒進(jìn)程,Linux,linux

?如上圖所示,當(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)行截圖

【Linux】詳解進(jìn)程狀態(tài)之僵尸進(jìn)程——孤兒進(jìn)程,Linux,linux

如上圖所示,當(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ū)別呢?

【Linux】詳解進(jìn)程狀態(tài)之僵尸進(jìn)程——孤兒進(jìn)程,Linux,linux

??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)行截圖:?

【Linux】詳解進(jìn)程狀態(tài)之僵尸進(jìn)程——孤兒進(jìn)程,Linux,linux

此外,我們還可以發(fā)送繼續(xù)的信號(hào)讓該進(jìn)程繼續(xù)執(zhí)行:

$ kill -18 (進(jìn)程PID)

?運(yùn)行截圖:【Linux】詳解進(jìn)程狀態(tài)之僵尸進(jìn)程——孤兒進(jìn)程,Linux,linux

?注意:

進(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)。

?【Linux】詳解進(jìn)程狀態(tài)之僵尸進(jìn)程——孤兒進(jìn)程,Linux,linux

?【Linux】詳解進(jìn)程狀態(tài)之僵尸進(jìn)程——孤兒進(jìn)程,Linux,linux

可以看見我們在第十行打了斷點(diǎn),此時(shí)觀看進(jìn)程狀態(tài):

【Linux】詳解進(jìn)程狀態(tài)之僵尸進(jìn)程——孤兒進(jìn)程,Linux,linux

?我們在調(diào)試中運(yùn)行一下:

【Linux】詳解進(jìn)程狀態(tài)之僵尸進(jìn)程——孤兒進(jìn)程,Linux,linux

觀看運(yùn)行狀態(tài):
【Linux】詳解進(jìn)程狀態(tài)之僵尸進(jìn)程——孤兒進(jìn)程,Linux,linux

??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)行;?

【Linux】詳解進(jìn)程狀態(tài)之僵尸進(jìn)程——孤兒進(jìn)程,Linux,linux

?此時(shí)當(dāng)我們執(zhí)行指令將子進(jìn)程”殺“掉,子進(jìn)程就會(huì)變成僵尸進(jìn)程;

$ kill -9 (子進(jìn)程PID)

【Linux】詳解進(jìn)程狀態(tài)之僵尸進(jìn)程——孤兒進(jìn)程,Linux,linux

其中我們能看到一個(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)程信息:

【Linux】詳解進(jìn)程狀態(tài)之僵尸進(jìn)程——孤兒進(jìn)程,Linux,linux

如上圖所示,子進(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ì)有什么危害.

?【Linux】詳解進(jìn)程狀態(tài)之僵尸進(jìn)程——孤兒進(jìn)程,Linux,linux文章來源地址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)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點(diǎn)僅代表作者本人,不代表本站立場。本站僅提供信息存儲(chǔ)空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請(qǐng)注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實(shí)不符,請(qǐng)點(diǎn)擊違法舉報(bào)進(jìn)行投訴反饋,一經(jīng)查實(shí),立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費(fèi)用

相關(guān)文章

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請(qǐng)作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包