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

【Linux從入門(mén)到放棄】進(jìn)程狀態(tài)的理解以及什么是僵尸進(jìn)程和孤兒進(jìn)程?

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

?????作者: @情話0.0
??專欄:《Linux從入門(mén)到放棄》
??個(gè)人簡(jiǎn)介:一名雙非編程菜鳥(niǎo),在這里分享自己的編程學(xué)習(xí)筆記,歡迎大家的指正與點(diǎn)贊,謝謝!

【Linux從入門(mén)到放棄】進(jìn)程狀態(tài)的理解以及什么是僵尸進(jìn)程和孤兒進(jìn)程?,LINUX從入門(mén)到放棄,linux,服務(wù)器,網(wǎng)絡(luò)


前言

此篇博客依然是在之前的學(xué)習(xí)基礎(chǔ)之上繼續(xù)探究關(guān)于進(jìn)程的知識(shí)。


一、進(jìn)程狀態(tài)

??首先大家可以思考一個(gè)問(wèn)題,當(dāng)電腦打開(kāi)一個(gè)客戶端程序,它是一直在被運(yùn)行嗎?

??答案當(dāng)然不是,一個(gè)進(jìn)程是不可能被一直運(yùn)行的,在計(jì)算機(jī)內(nèi)部都是多個(gè)進(jìn)程來(lái)回被調(diào)度的,之所以我們感覺(jué)它一直在運(yùn)行是因?yàn)檫M(jìn)程之間的切換速度太快了,人是感受不到切換帶來(lái)的延遲。

??進(jìn)程在運(yùn)行的時(shí)候是可以被操作系統(tǒng)管理、調(diào)度的,這里就有一個(gè)問(wèn)題,為什么這個(gè)進(jìn)程被調(diào)度呢?為什么不調(diào)度其他進(jìn)程呢?而這就取決于進(jìn)程狀態(tài)。

1.1 阻塞和掛起

要理解進(jìn)程狀態(tài)咱們先看一下這兩種狀態(tài):阻塞和掛起

阻塞:進(jìn)程因?yàn)榈却撤N條件就緒而導(dǎo)致的一種不推進(jìn)的狀態(tài),其實(shí)就是我們常說(shuō)的卡住了。阻塞一定是在等待某種資源,那么進(jìn)程卡住了其實(shí)就是等待著CPU來(lái)調(diào)度它,站在進(jìn)程的角度,它就是在等待獲取到CPU的資源。所以說(shuō)為什么阻塞呢?進(jìn)程就是通過(guò)等待的方式,等具體的資源被別的進(jìn)程使用完之后給自己拿到。
阻塞——進(jìn)程等待某種資源就緒的過(guò)程。

??但是,進(jìn)程是怎么等待的呢?
??這里提到的資源不僅有軟件資源,也有硬件資源(磁盤(pán)、網(wǎng)卡、顯卡等外設(shè))。操作系統(tǒng)不僅要對(duì)進(jìn)程管理,也得對(duì)這些資源做管理——先描述,再組織。于是也得為每個(gè)資源創(chuàng)建對(duì)應(yīng)的結(jié)構(gòu)體并鏈接起來(lái)。假設(shè)說(shuō)某個(gè)進(jìn)程現(xiàn)在缺少網(wǎng)卡這個(gè)硬件資源,那么操作系統(tǒng)就會(huì)將這個(gè)進(jìn)程的PCB與網(wǎng)卡資源的結(jié)構(gòu)體鏈接起來(lái),當(dāng)網(wǎng)卡資源被該進(jìn)程拿到時(shí),就會(huì)將該進(jìn)程的PCB重新鏈接到被CPU調(diào)度的執(zhí)行隊(duì)列中。

掛起:在阻塞的概念中,若一個(gè)進(jìn)程因沒(méi)有某種資源就會(huì)被鏈接到對(duì)應(yīng)資源的結(jié)構(gòu)隊(duì)列或鏈表中,而這些東西(進(jìn)程PCB、代碼數(shù)據(jù)、資源結(jié)構(gòu)隊(duì)列)都是存放在內(nèi)存中的,如果這樣的進(jìn)程太多的話就會(huì)一直占據(jù)著內(nèi)存的空間資源造成浪費(fèi),為了避免這種浪費(fèi)操作系統(tǒng)將那些長(zhǎng)時(shí)間不會(huì)被調(diào)度的進(jìn)程的代碼數(shù)據(jù)轉(zhuǎn)移到磁盤(pán)中,這樣就釋放了內(nèi)存的空間。而那些代碼數(shù)據(jù)被轉(zhuǎn)移到磁盤(pán)上的進(jìn)程就進(jìn)入了掛起狀態(tài)。

下面將學(xué)習(xí)關(guān)于Linux操作系統(tǒng)的進(jìn)程狀態(tài)變化:

static const char * const task_state_array[] = {
"R (running)", /*0*/
"S (sleeping)", /*1*/
"D (disk sleep)", /*2*/
"T (stopped)", /*4*/
"t (tracing stop)", /*8*/
"X (dead)", /*16*/
"Z (zombie)", /*32*/
};

??task_struct是一個(gè)結(jié)構(gòu)體,內(nèi)部包含這關(guān)于進(jìn)程的各種屬性,其中一個(gè)就是狀態(tài)。進(jìn)程狀態(tài)是通過(guò)一個(gè)數(shù)組來(lái)表示的,用不同的數(shù)字代表不同的狀態(tài)。

1.2 進(jìn)程只要是R狀態(tài),就一定是在CPU上運(yùn)行嗎?

??不一定,一個(gè)進(jìn)程現(xiàn)在處于R狀態(tài)并不代表你一定在CPU上運(yùn)行。也就是說(shuō),系統(tǒng)中可能會(huì)存在多個(gè)進(jìn)程是處于R狀態(tài)的,但是可能只有那么幾個(gè)在CPU上運(yùn)行,所以CPU在調(diào)度進(jìn)程時(shí)也一定要維護(hù)一個(gè)運(yùn)行隊(duì)列——將所有待運(yùn)行的進(jìn)程維護(hù)成一個(gè)隊(duì)列。當(dāng)CPU要調(diào)度進(jìn)程時(shí)就直接從這個(gè)隊(duì)列中挑選進(jìn)程即可。同時(shí)要說(shuō)明一個(gè)進(jìn)程是什么狀態(tài)一般也看這個(gè)進(jìn)程在哪里排隊(duì)。

1.2.1 這樣的進(jìn)程處于R狀態(tài)嗎?

#include <stdio.h>

int main()
{
	while(1)
	{  
		printf("我在運(yùn)行嗎???\n");
	}
	return 0;
}

運(yùn)行上面的代碼發(fā)現(xiàn)它陷入了死循環(huán),會(huì)不停的給顯示器上打印數(shù)據(jù)。那它是處于R狀態(tài)嗎?
經(jīng)過(guò)查看之后發(fā)現(xiàn)該進(jìn)程狀態(tài)并不是R,而是S+,該進(jìn)程不是跑得很歡實(shí)嗎,為甚么不是R狀態(tài)呢?

【Linux從入門(mén)到放棄】進(jìn)程狀態(tài)的理解以及什么是僵尸進(jìn)程和孤兒進(jìn)程?,LINUX從入門(mén)到放棄,linux,服務(wù)器,網(wǎng)絡(luò)

??這是因?yàn)楫?dāng)執(zhí)行打印語(yǔ)句得時(shí)候是需要訪問(wèn)顯示器這樣的外設(shè)資源,但是外設(shè)資源不可能直接被這個(gè)進(jìn)程申請(qǐng)到,因?yàn)樗€有可能被其他進(jìn)程所訪問(wèn),因此該進(jìn)程就得需要在這個(gè)外設(shè)等待隊(duì)列上進(jìn)行等待,而CPU的執(zhí)行速度非???,CPU不允許你在持有CPU資源的同時(shí)還去等待某種資源,因此當(dāng)查看進(jìn)程狀態(tài)的時(shí)候大部分就是S狀態(tài)。
??可是這個(gè)進(jìn)程總有在CPU運(yùn)行的時(shí)候吧,那我應(yīng)該能查到R狀態(tài)吧,可是怎么好像一直查不到呢?因?yàn)榇a很短,一瞬間就被執(zhí)行完了,而打印相對(duì)比較慢,可能1s的時(shí)間 99.9% 都是在等待的,所以在查看時(shí)可能得上萬(wàn)次才能查到一次R狀態(tài)。

1.2.1 為什么這樣的進(jìn)程處于R狀態(tài)?

??當(dāng)把那一行打印語(yǔ)句注釋掉之后就會(huì)發(fā)現(xiàn)該進(jìn)程又處于R狀態(tài),很明顯,問(wèn)題出現(xiàn)在那一行打印語(yǔ)句上。

【Linux從入門(mén)到放棄】進(jìn)程狀態(tài)的理解以及什么是僵尸進(jìn)程和孤兒進(jìn)程?,LINUX從入門(mén)到放棄,linux,服務(wù)器,網(wǎng)絡(luò)

??而將那行代碼注釋掉,該進(jìn)程就處于R狀態(tài),這是因?yàn)椴挥迷L問(wèn)外設(shè),while循環(huán)就是個(gè)判斷語(yǔ)句,是純計(jì)算的代碼。在整個(gè)進(jìn)程調(diào)度的生命周期里只會(huì)用CPU資源,只要被調(diào)度就一直是R狀態(tài),只要被查看就一直是R狀態(tài)。
??歸根結(jié)底就是CPU太快了。

1.3 休眠狀態(tài)

??在上面的內(nèi)容我們已經(jīng)了解了S狀態(tài),表示可中斷休眠,本質(zhì)就是一種阻塞狀態(tài)。
??而D休眠狀態(tài)表示的是不可中斷休眠,但是對(duì)于我們來(lái)說(shuō)一般用不著。對(duì)于D狀態(tài)舉個(gè)簡(jiǎn)單例子解釋一下:
??假設(shè)內(nèi)存中某個(gè)進(jìn)程有1GB的數(shù)據(jù)要寫(xiě)到磁盤(pán)上,于是在與磁盤(pán)交涉之后就開(kāi)始往磁盤(pán)上寫(xiě),畢竟磁盤(pán)的讀寫(xiě)速度較慢,因此這個(gè)進(jìn)程的狀態(tài)被設(shè)置為阻塞狀態(tài),然后在磁盤(pán)的內(nèi)核數(shù)據(jù)隊(duì)列中等待排隊(duì)??墒蔷驮诖疟P(pán)兢兢業(yè)業(yè)的拷貝數(shù)據(jù)的時(shí)候操作系統(tǒng)路過(guò)發(fā)現(xiàn)內(nèi)存都忙成什么樣了,怎么還有進(jìn)程在這啥也不干還占著空間,于是就殺掉了這個(gè)進(jìn)程。之后呢磁盤(pán)因?yàn)槟撤N原因?qū)е聦?xiě)失敗,于是磁盤(pán)就要去找那個(gè)進(jìn)程,可是發(fā)現(xiàn)怎么不見(jiàn)了,這就會(huì)導(dǎo)致數(shù)據(jù)的丟失。
??那這個(gè)后果到底是誰(shuí)的鍋呢?磁盤(pán)??jī)?nèi)存還是操作系統(tǒng)呢?其實(shí)都不是它們的鍋,而是操作系統(tǒng)設(shè)計(jì)者的鍋。實(shí)際上只要保證這個(gè)進(jìn)程不能被殺死即可。于是就有了D狀態(tài)。

1.4 暫停狀態(tài)

??T表示暫停狀態(tài),可通過(guò)指令的方式將一個(gè)進(jìn)程的狀態(tài)改為T(mén)狀態(tài)。

#include <stdio.h>
#include <unistd.h>
int main()
{
	int count=0;
	while(1)
	{  
		printf("我再運(yùn)行嗎??? count:%d\n",count++);
		sleep(1);
	}
	return 0;
}

運(yùn)行上面的代碼我們知道會(huì)一直打印并且該進(jìn)程的狀態(tài)基本上都是S狀態(tài),我們可以通過(guò)發(fā)送19號(hào)信號(hào)(SIGSTOP)來(lái)暫停該進(jìn)程,然后可再通過(guò)18號(hào)信號(hào)(SIGCONT)恢復(fù)該進(jìn)程。

  1. 暫停進(jìn)程
    【Linux從入門(mén)到放棄】進(jìn)程狀態(tài)的理解以及什么是僵尸進(jìn)程和孤兒進(jìn)程?,LINUX從入門(mén)到放棄,linux,服務(wù)器,網(wǎng)絡(luò)
  2. 恢復(fù)進(jìn)程
    【Linux從入門(mén)到放棄】進(jìn)程狀態(tài)的理解以及什么是僵尸進(jìn)程和孤兒進(jìn)程?,LINUX從入門(mén)到放棄,linux,服務(wù)器,網(wǎng)絡(luò)
    此時(shí)發(fā)現(xiàn)進(jìn)程又像之前一樣開(kāi)始打印數(shù)據(jù)了,只是該進(jìn)程的狀態(tài)沒(méi)有之前的 ‘+’,除此之外就是發(fā)現(xiàn)ctrl+c 并不能結(jié)束掉該進(jìn)程。這是因?yàn)槿绻麪顟B(tài)帶了 ‘+’ 表示在前臺(tái)運(yùn)行,前臺(tái)進(jìn)程你可以ctrl+c 終止進(jìn)程。但沒(méi)有 ‘+’ 表示后臺(tái)運(yùn)行,就像上面代碼一樣一直打印數(shù)據(jù),此時(shí)要想殺掉該進(jìn)程就可通過(guò)9號(hào)信號(hào)殺死該進(jìn)程。
    【Linux從入門(mén)到放棄】進(jìn)程狀態(tài)的理解以及什么是僵尸進(jìn)程和孤兒進(jìn)程?,LINUX從入門(mén)到放棄,linux,服務(wù)器,網(wǎng)絡(luò)

1.5 僵尸狀態(tài)(僵尸進(jìn)程)

??要談僵尸狀態(tài),我們先思考一下為什么要?jiǎng)?chuàng)建進(jìn)程?——讓進(jìn)程幫助我們辦事,完成某項(xiàng)任務(wù)。當(dāng)然對(duì)于完成的結(jié)果我們可以關(guān)心,也可以不關(guān)心。今天我們只談關(guān)心結(jié)果。
??我們一般在寫(xiě)main函數(shù)時(shí),最后都會(huì)寫(xiě)一句return 0;,而這個(gè)o表示這個(gè)main函數(shù)的退出碼,可以通過(guò)這個(gè)退出碼來(lái)判斷進(jìn)程執(zhí)行后的結(jié)果。
??如果一個(gè)進(jìn)程退出了,立馬X狀態(tài),立馬退出,那么父進(jìn)程有沒(méi)有機(jī)會(huì)拿到退出結(jié)果呢?——在Linux中,當(dāng)進(jìn)程退出的時(shí)候,一般不會(huì)立即徹底退出,而是要維持一個(gè)狀態(tài)叫做Z,也叫做僵尸狀態(tài)。這種狀態(tài)方便后續(xù)父進(jìn)程或OS讀取子進(jìn)程的退出結(jié)果,所以,只要子進(jìn)程退出,父進(jìn)程還在運(yùn)行,但父進(jìn)程沒(méi)有讀取子進(jìn)程狀態(tài),子進(jìn)程進(jìn)入Z狀態(tài)。

#include <stdio.h>
#include <unistd.h>
int main()
{
  pid_t id=fork();
  if(id==0)
  {
    //子進(jìn)程
    while(1)
    {
      printf("i am child,pid:%d,ppid:%d\n",getpid(),getppid());
      sleep(1);
    }
  }
  else if(id>0)
  {
  	//父進(jìn)程
    while(1)
    {
      printf("i am father,pid:%d,ppid:%d\n",getpid(),getppid());
      sleep(1);
    }
  }
  return 0;
}

【Linux從入門(mén)到放棄】進(jìn)程狀態(tài)的理解以及什么是僵尸進(jìn)程和孤兒進(jìn)程?,LINUX從入門(mén)到放棄,linux,服務(wù)器,網(wǎng)絡(luò)
??當(dāng)通過(guò)kill命令殺死了子進(jìn)程之后,子進(jìn)程的狀態(tài)就變成了Z+,此時(shí)它就必須一直被維持下去,直到父進(jìn)程讀取到它的退出結(jié)果。
??維護(hù)退出狀態(tài)本身就是要用數(shù)據(jù)維護(hù),也屬于進(jìn)程基本信息,所以保存在task_struct(PCB)中,也就是說(shuō),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)存,從而造成內(nèi)存泄漏。

二、孤兒進(jìn)程

??在學(xué)習(xí)了僵尸進(jìn)程之后明白了子進(jìn)程在父進(jìn)程之前退出,如果父進(jìn)程一直不獲取子進(jìn)程的退出結(jié)果,那么子進(jìn)程就會(huì)進(jìn)入僵尸狀態(tài),子進(jìn)程也就成了僵尸進(jìn)程。
??那什么是孤兒進(jìn)程呢?

2.1 什么是孤兒進(jìn)程?

??從名字其實(shí)就可以感受到,孤兒就是了沒(méi)有了父母,也就是父進(jìn)程先退出,而子進(jìn)程沒(méi)有了父進(jìn)程獲取它的退出結(jié)果,那么子進(jìn)程就變成了孤兒進(jìn)程。之所以父進(jìn)程正常退出沒(méi)有變成僵尸狀態(tài)那是因?yàn)?strong>父進(jìn)程的父進(jìn)程是bash,父進(jìn)程退出的時(shí)候bash獲取到了父進(jìn)程的退出結(jié)果。

2.2 孤兒進(jìn)程周邊

#include <stdio.h>
#include <unistd.h>

int main()
{
	pid_t id=fork();
	if(id==0)
	{
    	//子進(jìn)程
   		while(1)
    	{
      		printf("i am child,pid:%d,ppid:%d\n",getpid(),getppid());
      		sleep(1);
    	}
  	}
  	else if(id>0)
  	{
    	//父進(jìn)程 
    	int cnt=10;
    	while(1)
    	{
      		printf("i am father,pid:%d,ppid:%d\n",getpid(),getppid());
      		if(cnt-- <= 0) break;
      		sleep(1);
    	}
  	}
 	return 0;
}

代碼功能: 通過(guò)fork創(chuàng)建子進(jìn)程,子進(jìn)程一直循環(huán)打印,父進(jìn)程在十秒之后退出。

//查看進(jìn)程的狀態(tài)信息
while :; do ps axj | head -1 && ps axj | grep myproc | grep myproc | grep -v grep; sleep 1; echo "-----------"; done;

【Linux從入門(mén)到放棄】進(jìn)程狀態(tài)的理解以及什么是僵尸進(jìn)程和孤兒進(jìn)程?,LINUX從入門(mén)到放棄,linux,服務(wù)器,網(wǎng)絡(luò)
【Linux從入門(mén)到放棄】進(jìn)程狀態(tài)的理解以及什么是僵尸進(jìn)程和孤兒進(jìn)程?,LINUX從入門(mén)到放棄,linux,服務(wù)器,網(wǎng)絡(luò)

??上面兩幅圖分別是代碼剛開(kāi)始運(yùn)行所查到的進(jìn)程信息和在十秒之后的進(jìn)程狀態(tài)信息,發(fā)現(xiàn)前十秒父子進(jìn)程都在正常運(yùn)行,父進(jìn)程PID為2453,子進(jìn)程PID為2454。十秒之后,父進(jìn)程退出,關(guān)于PID為2453的進(jìn)程狀態(tài)信息已沒(méi)有,只剩下了子進(jìn)程的狀態(tài)信息。值得注意的是,此時(shí)子進(jìn)程的父進(jìn)程PID變成了1,并且它的狀態(tài)變成了S,為后臺(tái)進(jìn)程,需要kill命令將這個(gè)進(jìn)程殺死掉kill -9 2454 或者 killall myproc。
??孤兒進(jìn)程——在父進(jìn)程退出之后,子進(jìn)程就會(huì)被操作系統(tǒng)自動(dòng)領(lǐng)養(yǎng)(讓1號(hào)進(jìn)程成為新的父進(jìn)程)。

??為什么操作系統(tǒng)會(huì)這樣做呢?
??如果不這樣做,那么子進(jìn)程在退出之后會(huì)因沒(méi)有父進(jìn)程讀取它的退出結(jié)果而處于一種游離狀態(tài),一直占據(jù)著相關(guān)的內(nèi)存結(jié)構(gòu)(內(nèi)存泄露)。


總結(jié)

此篇博客首先就是關(guān)于進(jìn)程的幾種狀態(tài)做了解釋,主要就是對(duì)阻塞和掛起的理解。再者就是明對(duì)僵尸狀態(tài)和僵尸進(jìn)程的理解,如果子進(jìn)程先退出而父進(jìn)程又一直不獲取子進(jìn)程的退出結(jié)果,那么子進(jìn)程就變成了僵尸進(jìn)程。最后就是對(duì)孤兒進(jìn)程的介紹,明白父進(jìn)程先退出那么子進(jìn)程就變成了孤兒進(jìn)程同時(shí)會(huì)被1號(hào)進(jìn)程領(lǐng)養(yǎng)。文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-542723.html

到了這里,關(guān)于【Linux從入門(mén)到放棄】進(jìn)程狀態(tài)的理解以及什么是僵尸進(jìn)程和孤兒進(jìn)程?的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來(lái)自互聯(lián)網(wǎng)用戶投稿,該文觀點(diǎn)僅代表作者本人,不代表本站立場(chǎng)。本站僅提供信息存儲(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)文章

覺(jué)得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

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

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

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包