欧美free性护士vide0shd,老熟女,一区二区三区,久久久久夜夜夜精品国产,久久久久久综合网天天,欧美成人护士h版

目錄

柚子快報(bào)激活碼778899分享:運(yùn)維 【Linux】進(jìn)程狀態(tài)

柚子快報(bào)激活碼778899分享:運(yùn)維 【Linux】進(jìn)程狀態(tài)

http://yzkb.51969.com/

【Linux】進(jìn)程狀態(tài)

1. 為什么要有狀態(tài)1.1 基于時(shí)間片輪詢1.2 簡(jiǎn)單描述進(jìn)程排隊(duì)1.3 運(yùn)行狀態(tài)1.4 阻塞狀態(tài)1.5 掛起狀態(tài)

2. Linux下的狀態(tài)信息3. Linux下具體的進(jìn)程狀態(tài)3.1 運(yùn)行狀態(tài)R3.2 可中斷睡眠-淺度睡眠-S3.3 可不中斷睡眠-深度睡眠-D3.4 停止?fàn)顟B(tài)-T3.5 停止?fàn)顟B(tài)-t3.6 死亡狀態(tài)-X3.7 僵尸狀態(tài)-Z3.7.1 僵尸進(jìn)程的危害

4. 孤兒進(jìn)程

1. 為什么要有狀態(tài)

1.1 基于時(shí)間片輪詢

首先我們大部分的電腦都只有一個(gè)CPU,但是我們的電腦去可以同時(shí)執(zhí)行多個(gè)應(yīng)用程序,比如我們同時(shí)登錄了QQ和微信,也可能同時(shí)在看抖音。所以說(shuō)雖然我們的CPU只有一個(gè)但是可以同時(shí)運(yùn)行多個(gè)應(yīng)用程序(進(jìn)程)。也就是說(shuō)我們啟動(dòng)的一個(gè)進(jìn)程并不是一直在運(yùn)行的,雖然進(jìn)程需要在CPU中運(yùn)行,但是并不是一直在CPU上一直進(jìn)行運(yùn)行的。而是進(jìn)行輪詢的方式占用CPU的資源,是基于一種時(shí)間片的方式進(jìn)行,就是給每個(gè)進(jìn)程占用CPU資源的時(shí)間,一旦時(shí)間過(guò)了就需要從CPU中下來(lái)讓另個(gè)一進(jìn)程進(jìn)行占用,保證其他進(jìn)程可以占用CPU資源,這也是為什么只有一個(gè)CPU,卻可以同時(shí)有多個(gè)進(jìn)程在運(yùn)行。

1.2 簡(jiǎn)單描述進(jìn)程排隊(duì)

前面我們也已經(jīng)說(shuō)過(guò)了其實(shí)進(jìn)程=內(nèi)核數(shù)據(jù)(task_struct) + 可執(zhí)行程序。所以我們讓進(jìn)程去排隊(duì)是讓可執(zhí)行程序去排隊(duì)還是讓task_struct去排隊(duì)呢?就好比我們?nèi)ッ嬖?,我們肯定是先讓我們的?jiǎn)歷去進(jìn)行排隊(duì)。所以讓一個(gè)進(jìn)程去排隊(duì)其實(shí)是讓task_struct去排隊(duì)。但是這里又有一個(gè)問(wèn)題,前面我們不是講過(guò)了,task_struct是通過(guò)鏈表進(jìn)行連接的,到這里怎么就又是隊(duì)列了呢?這里我們需要補(bǔ)充一個(gè)知識(shí)點(diǎn)就是一個(gè)task_struct是可以被連入多個(gè)數(shù)據(jù)結(jié)構(gòu)中的。

在我們以前學(xué)習(xí)雙聯(lián)報(bào)表的時(shí)候是這樣實(shí)現(xiàn)的:

但是在Linux下并不是這樣實(shí)現(xiàn)的,而是下面這樣實(shí)現(xiàn)的:

那么到這里有小伙伴就可能有疑問(wèn)了,如果我們只是拿著listnode去進(jìn)行連接,那怎么找到task_struct的首地址呢?所以這個(gè)時(shí)候就需要用到偏移量了,是不是只要知道n在task_struct里的偏移量,在使用n的地址減去偏移量就找到了t的地址了。具體做法:(task_struct*)(&n - &((task_struct*)0->n);

而是用這樣的方式我們就可以不止定義一個(gè)listnode結(jié)構(gòu)體,在task_struct中我們可以定義多個(gè)這樣的listnode,就可以實(shí)現(xiàn)使用多種數(shù)據(jù)結(jié)構(gòu)將task_struct進(jìn)行管理起來(lái),并且這樣做的話,我們想要在添加新的數(shù)據(jù)結(jié)構(gòu),并不需要將原來(lái)的數(shù)據(jù)接機(jī)構(gòu)進(jìn)行清除,而是在添加listnode結(jié)構(gòu)體,進(jìn)行新從數(shù)據(jù)結(jié)構(gòu)連接。

1.3 運(yùn)行狀態(tài)

所謂狀態(tài)就是決定了后序的動(dòng)作,Linux下可能存在多個(gè)進(jìn)程都要根據(jù)它的狀態(tài)執(zhí)行后序的動(dòng)作。比如一個(gè)進(jìn)程不可能一直都處于運(yùn)行狀態(tài),他可能在等待軟硬件資源,而在等待的過(guò)程中是不需要進(jìn)行消耗CPU資源的,也就可以不用加載到CPU中占用CPU資源。而一個(gè)CPU會(huì)有一個(gè)運(yùn)行隊(duì)列,被加載到隊(duì)列中的進(jìn)程都可以認(rèn)為是運(yùn)行狀態(tài)的,這個(gè)隊(duì)列會(huì)基于時(shí)間片的方式進(jìn)行輪詢是使每個(gè)被加載到隊(duì)列中的task_struct都可以享受到CPU的資源。那么就是根據(jù)什么,CPU知道需要將進(jìn)程加載到運(yùn)行隊(duì)列中呢?答案就是進(jìn)程狀態(tài)。在一些教材中常見(jiàn)的狀態(tài)有運(yùn)行,阻塞,掛起,只有狀態(tài)處于運(yùn)行狀態(tài)才可以被加載到運(yùn)行隊(duì)列中。

1.4 阻塞狀態(tài)

比如我們寫(xiě)了一個(gè)scnaf()函數(shù)從鍵盤(pán)中獲取數(shù)據(jù),當(dāng)我們運(yùn)行這個(gè)程序的時(shí)候,首先是需要加載到CPU中的,但是一旦執(zhí)行到scnaf()這個(gè)函數(shù),此時(shí)進(jìn)程在等待硬件的資源,可是CPU(操作系統(tǒng))并不知道你要等待多久,那么如果一直在CPU中進(jìn)行等待的話就會(huì)浪費(fèi)CPU的資源,所以這個(gè)時(shí)候操作系統(tǒng)就會(huì)將該進(jìn)程的狀態(tài)設(shè)置為阻塞狀態(tài),并把該進(jìn)程放到鍵盤(pán)設(shè)備的等待隊(duì)列(你沒(méi)有聽(tīng)錯(cuò),不只是CPU有運(yùn)行隊(duì)列,其他設(shè)備也有自己的隊(duì)列,CPU也是設(shè)備)設(shè)置該進(jìn)程為阻塞狀態(tài)。只有當(dāng)該進(jìn)程從鍵盤(pán)中拿到了數(shù)據(jù),此時(shí)操作系統(tǒng)才會(huì)將該進(jìn)程更新?tīng)顟B(tài)為運(yùn)行狀態(tài)并,重新放到CPU運(yùn)行隊(duì)列中。

所以當(dāng)我們的進(jìn)程在等待軟硬件資源的時(shí)候,資源如果沒(méi)有就緒,我們的進(jìn)程task_struct只能第一將自己設(shè)置為阻塞狀態(tài),第二將自己的PCB連入等待的資源提供的的等待隊(duì)列。也就是說(shuō)狀態(tài)的變遷,引起的是PCB會(huì)被操作系統(tǒng)變遷到不同的隊(duì)列中。

1.5 掛起狀態(tài)

而掛起這里我們只談阻塞掛起,有些像運(yùn)行掛起之類的我們這里不進(jìn)行講解。當(dāng)計(jì)算機(jī)資源比較吃緊的時(shí)候,內(nèi)存占用情況比較嚴(yán)重,這個(gè)時(shí)候。如果我們還將在內(nèi)存中加載進(jìn)程的話將要面臨的問(wèn)題第一要么進(jìn)程直接掛掉,第二就是將內(nèi)存進(jìn)行站樁騰挪擠出空間供進(jìn)程使用。所以操作系統(tǒng)會(huì)將處于阻塞狀態(tài)的進(jìn)程中的代碼和數(shù)據(jù)交換到磁盤(pán)上這操作叫做換入=出操作,將內(nèi)存騰出空間來(lái),磁盤(pán)上有固定的一塊區(qū)域,專門(mén)用來(lái)當(dāng)內(nèi)存資源緊張的時(shí)候,將內(nèi)存中的數(shù)據(jù)進(jìn)行換入換成,這個(gè)部分叫做swap分區(qū)。一旦阻塞狀態(tài)被更新為運(yùn),行狀態(tài),在從磁盤(pán)上重新?lián)Q入操作。但是這里的全部前提都是進(jìn)程的PCB是不會(huì)別換出的,這想到不用想,如果PCB也別換出去了,誰(shuí)知道這進(jìn)程到底要不要換入??!所以這里我們其實(shí)也可以推測(cè)出一個(gè)進(jìn)程的加載過(guò)程,一個(gè)進(jìn)程的加載時(shí)先創(chuàng)建的PCB并加載了PCB,再是將代碼和數(shù)據(jù)進(jìn)行加載的,也就是說(shuō)一個(gè)進(jìn)程其實(shí)只要PCB有了,后序的數(shù)據(jù)和代碼都是可以進(jìn)行慢慢的加載過(guò)來(lái)的。

那么是不是我們的swap分區(qū)越大越好呢?首先我們要分析一下?lián)Q出其實(shí)本質(zhì)是把數(shù)據(jù)拷貝到外設(shè),換入的本質(zhì)其實(shí)就是將數(shù)據(jù)拷貝會(huì)內(nèi)存。我們之前在將馮諾依曼的時(shí)候,數(shù)據(jù)從外設(shè)到內(nèi)存,從內(nèi)存到外設(shè),本質(zhì)在內(nèi)存訪問(wèn)的時(shí),我們?cè)L問(wèn)外設(shè)的動(dòng)作一定是比較慢的,所以在換入和換出的操作本質(zhì)就是用效率換取系統(tǒng)的可用性。一旦我們將swap分區(qū)設(shè)置的很大,那么操作系統(tǒng)就會(huì)很依賴swap分區(qū),帶來(lái)的結(jié)果就是內(nèi)存和外設(shè)進(jìn)行IO的次數(shù)的頻率就會(huì)非常的高,結(jié)果就是低效的操作的比重就高了,那么整體的效率也就下降了。所以一般是將swap分區(qū)設(shè)置為內(nèi)存大小的一半。

2. Linux下的狀態(tài)信息

其實(shí)所謂狀態(tài),本質(zhì)上其實(shí)就是一個(gè)整形變量,是在task_struct屬性中的一個(gè)整形變量。

/*

* The task state array is a strange "bitmap" of

* reasons to sleep. Thus "running" is zero, and

* you can test for combinations of others with

* simple bit tests.

*/

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 */

};

狀態(tài)狀態(tài)描述R運(yùn)行狀態(tài)(running)并不意味著進(jìn)程一定在運(yùn)行中,它表明進(jìn)程要么是在運(yùn)行中要么在運(yùn)行隊(duì)列里。S睡眠狀態(tài)(sleeping)意味著進(jìn)程在等待事件完成(這里的睡眠有時(shí)候也叫做可中斷睡眠(interruptible sleep))。D磁盤(pán)休眠狀態(tài)(Disk sleep)有時(shí)候也叫不可中斷睡眠狀態(tài)(uninterruptible sleep),在這個(gè)狀態(tài)的進(jìn)程通常會(huì)等待IO的結(jié)束。T停止?fàn)顟B(tài)(stopped)可以通過(guò)發(fā)送 SIGSTOP 信號(hào)給進(jìn)程來(lái)停止(T)進(jìn)程。這個(gè)被暫停的進(jìn)程可以通過(guò)發(fā)送 SIGCONT 信號(hào)讓進(jìn)程繼續(xù)運(yùn)行。X死亡狀態(tài)(dead)這個(gè)狀態(tài)只是一個(gè)返回狀態(tài),你不會(huì)在任務(wù)列表里看到這個(gè)狀態(tài)Z(zombie)-僵尸進(jìn)程僵死狀態(tài)(Zombies)是一個(gè)比較特殊的狀態(tài)。當(dāng)進(jìn)程退出并且父進(jìn)程(使用wait()系統(tǒng)調(diào)用,后面講)沒(méi)有讀取到子進(jìn)程退出的返回代碼時(shí)就會(huì)產(chǎn)生僵死(尸)進(jìn)程

3. Linux下具體的進(jìn)程狀態(tài)

3.1 運(yùn)行狀態(tài)R

R運(yùn)行狀態(tài)(running)并不意味著進(jìn)程一定在運(yùn)行中,它表明進(jìn)程要么是在運(yùn)行中要么在運(yùn)行隊(duì)列里。

int main()

{

while (1)

{}

return 0;

}

3.2 可中斷睡眠-淺度睡眠-S

S睡眠狀態(tài)(sleeping)意味著進(jìn)程在等待事件完成(這里的睡眠有時(shí)候也叫做可中斷睡眠(interruptible sleep))。 其實(shí)就等同于上面?zhèn)€我們講的進(jìn)程阻塞狀態(tài)。

int main()

{

int a = 0;

scanf("%d", &a);

printf("a=%d\n", a);

return 0;

}

S+后面這個(gè)加號(hào)表示前臺(tái)運(yùn)行,沒(méi)有加號(hào)表示后臺(tái)運(yùn)行。

“+“代表是前臺(tái)運(yùn)行,無(wú)”+“代表后臺(tái)運(yùn)行,后臺(tái)運(yùn)行時(shí)可在命令行繼續(xù)輸入指令并執(zhí)行,但無(wú)法用ctrl+c結(jié)束,需要用kill -9 pid殺死。想要后臺(tái)運(yùn)行某個(gè)程序就在后面加”&”,如:./test &

3.3 可不中斷睡眠-深度睡眠-D

在這里D狀態(tài)我們無(wú)法使用代碼進(jìn)行演示。我們只能簡(jiǎn)單的說(shuō)明它的原理。

前面我們說(shuō)過(guò)了,如果內(nèi)存資源比較吃緊的話,操作系統(tǒng)是會(huì)讓一些處于阻塞狀態(tài)的進(jìn)程進(jìn)行換入,把數(shù)據(jù)和代碼拷貝到磁盤(pán)上,進(jìn)而把空間進(jìn)行暫時(shí)的騰挪出來(lái)。但是如果內(nèi)存資源非常的吃緊,操作系統(tǒng)是有權(quán)利直接把進(jìn)程給殺掉的。所以這就會(huì)導(dǎo)致一個(gè)問(wèn)題,一旦一個(gè)進(jìn)程正處于阻塞狀態(tài),它在通知磁盤(pán)設(shè)備將數(shù)據(jù)拷貝到磁盤(pán)上,并等待磁盤(pán)回復(fù)拷貝情況,這個(gè)時(shí)候內(nèi)存資源非常的吃緊,而操作系統(tǒng)有正好的檢測(cè)到了這個(gè)進(jìn)程,并將其殺掉了,而這個(gè)時(shí)候磁盤(pán)拷貝失敗了并將結(jié)果告訴進(jìn)程,可是發(fā)現(xiàn)找不到這個(gè)進(jìn)程了,于是就將數(shù)據(jù)給丟棄了。從這個(gè)過(guò)程中我們發(fā)現(xiàn),如果這個(gè)數(shù)據(jù)是非常重要的話,引發(fā)的結(jié)果不敢想想,所以這里就需要有一個(gè)狀態(tài),類似于免死金牌,到操作系統(tǒng)檢測(cè)到進(jìn)程時(shí),進(jìn)程出示免死金牌,操作系統(tǒng)就不會(huì)將其殺死。

當(dāng)然一般都不會(huì)出現(xiàn)上面的狀況,因?yàn)橐坏┏霈F(xiàn)D狀態(tài)就說(shuō)明當(dāng)前的系統(tǒng)資源已經(jīng)非常的吃緊了,上面的狀況也可以說(shuō)明為什么有時(shí)候我們打開(kāi)了很多的引用程序后,有時(shí)候有些程序就強(qiáng)制推出了的原因。而D狀態(tài)其實(shí)本質(zhì)上也是阻塞狀態(tài)的一種

3.4 停止?fàn)顟B(tài)-T

前面我們使用了kill -9 殺死一個(gè)進(jìn)程,這個(gè)其實(shí)是一個(gè)信號(hào),后面我們會(huì)講信號(hào),這里我們就先看一下有哪些信號(hào)。

這里會(huì)發(fā)現(xiàn)一個(gè)19號(hào)信號(hào)SIGSTOP,就是一個(gè)暫停信號(hào)。

如果要讓他繼續(xù)運(yùn)行可以使用18號(hào)信號(hào)SIGCONT 其實(shí)上上面我們也發(fā)現(xiàn)了,一點(diǎn)我們暫停了,就自動(dòng)變成了后端運(yùn)行了,當(dāng)我們重新啟動(dòng)的時(shí)候也是變成了后端運(yùn)行了,這其實(shí)也符合廠里,既然是你主動(dòng)給我暫停了,那么就不因該讓前臺(tái)繼續(xù)運(yùn)行了。如果要將其停止,只能使用kill -9將其殺掉。

而至于上面的不是R運(yùn)行狀態(tài),而是S睡眠狀態(tài),主要原因是我們打印數(shù)據(jù)其實(shí)是顯示到顯示屏上的,而顯示屏其實(shí)也算是外設(shè),而我們的CPU執(zhí)行printf這個(gè)指令其實(shí)是非常的快速的,而至于打印出來(lái)其實(shí)不關(guān)CPU的事情了,所以者時(shí)候進(jìn)程其實(shí)一直處于等待顯示器顯示打印結(jié)果的過(guò)程,所以才顯示為S狀態(tài)。

3.5 停止?fàn)顟B(tài)-t

t也是一種暫停狀態(tài)。

而暫停狀態(tài)其實(shí)也是一種阻塞狀態(tài)。

3.6 死亡狀態(tài)-X

死亡狀態(tài)只是一個(gè)返回狀態(tài),當(dāng)一個(gè)進(jìn)程的退出信息被讀取后,該進(jìn)程所申請(qǐng)的資源就會(huì)立即被釋放,該進(jìn)程也就不存在了,所以你不會(huì)在任務(wù)列表當(dāng)中看到死亡狀態(tài),死亡狀態(tài)是一個(gè)瞬時(shí)過(guò)程,我們很難查看到。

3.7 僵尸狀態(tài)-Z

一個(gè)進(jìn)程被創(chuàng)建出來(lái)就是用來(lái)幫忙干事情的,一點(diǎn)這個(gè)進(jìn)程死了,我們要不要知道這個(gè)進(jìn)程為什么死掉了,交給這個(gè)進(jìn)程干的事情干的怎么樣子了。這些都需要提供給創(chuàng)建它的那個(gè)。也就是說(shuō)需要獲取這個(gè)進(jìn)程的退出數(shù)據(jù),所以一個(gè)進(jìn)程退出了,它的代碼和數(shù)據(jù)可以直接釋放,因?yàn)椴粫?huì)再進(jìn)行執(zhí)行了,但是它所對(duì)應(yīng)的PCB不因該立馬被釋放,這樣是為了讓系統(tǒng)或者創(chuàng)建它的進(jìn)程獲取它的數(shù)據(jù)。

僵死狀態(tài)(Zombies)是一個(gè)比較特殊的狀態(tài)。當(dāng)進(jìn)程退出并且父進(jìn)程(使用wait()系統(tǒng)調(diào)用,后面講)沒(méi)有讀取到子進(jìn)程退出的返回代碼時(shí)就會(huì)產(chǎn)生僵死(尸)進(jìn)程僵死進(jìn)程會(huì)以終止?fàn)顟B(tài)保持在進(jìn)程表中,并且會(huì)一直在等待父進(jìn)程讀取退出狀態(tài)代碼。所以,只要子進(jìn)程退出,父進(jìn)程還在運(yùn)行,但父進(jìn)程沒(méi)有讀取子進(jìn)程狀態(tài),子進(jìn)程進(jìn)入Z狀態(tài)。

#include

#include

#include

#include

int main()

{

pid_t id = fork();

if (id == 0)

{

int cnt = 3;

while (cnt)

{

printf("child[%d] is begin Z...\n", getpid());

sleep(1);

cnt--;

}

exit(0); // 直接讓子進(jìn)程退出

}

while (1)

{

// 父進(jìn)程一直運(yùn)行,但是不讀取子進(jìn)程的狀態(tài)信息

printf("parent[%d] is sleeping...\n", getpid());

sleep(1);

}

return 0;

}

3.7.1 僵尸進(jìn)程的危害

為什么要有僵尸狀態(tài)呢?

創(chuàng)建一個(gè)進(jìn)程的目的時(shí)希望這個(gè)進(jìn)程可以幫我們完成工作,所以子進(jìn)程必須有結(jié)果數(shù)據(jù),而結(jié)果數(shù)據(jù)時(shí)保存在PCB中的。所以進(jìn)程的代碼和數(shù)據(jù)可以釋放,但是PCB不能立即釋放,必須等到PCB中的數(shù)據(jù)被父進(jìn)程拿走才可以釋放。所以子進(jìn)程就必須維持當(dāng)前現(xiàn)狀,供上層讀取。

如果父進(jìn)程一直不讀取呢?

維護(hù)退出狀態(tài)本身就是要用數(shù)據(jù)維護(hù),也屬于進(jìn)程基本信息,所以保存在task_struct(PCB)中,換句話說(shuō),Z狀態(tài)一直不退出,PCB一直都要維護(hù),而PCB是要占居內(nèi)存的。所以如果一個(gè)進(jìn)程創(chuàng)建了很多的子進(jìn)程,但是就是一直不回收子進(jìn)程的退出信息,那么PCB就會(huì)一直存在,就會(huì)導(dǎo)致內(nèi)存泄漏。

為什么我們?cè)诿钚袉?dòng)的進(jìn)程不需要讀取進(jìn)程退出信息

那是因?yàn)槲覀冊(cè)诿钚袆?chuàng)建的進(jìn)程都是是bash的子進(jìn)程,而bash會(huì)自動(dòng)的讀取進(jìn)程的退出信息。

4. 孤兒進(jìn)程

父進(jìn)程如果提前退出,那么子進(jìn)程后退出,進(jìn)入Z之后,那該如何處理呢?父進(jìn)程先退出,子進(jìn)程就稱之為“孤兒進(jìn)程”孤兒進(jìn)程被1號(hào)init進(jìn)程領(lǐng)養(yǎng)我們認(rèn)為就是操作系統(tǒng)領(lǐng)養(yǎng)的,當(dāng)然要有init進(jìn)程回收嘍。

并且一個(gè)進(jìn)程變成孤兒后,他還會(huì)變成后臺(tái)進(jìn)程。

柚子快報(bào)激活碼778899分享:運(yùn)維 【Linux】進(jìn)程狀態(tài)

http://yzkb.51969.com/

相關(guān)文章

評(píng)論可見(jiàn),查看隱藏內(nèi)容

本文內(nèi)容根據(jù)網(wǎng)絡(luò)資料整理,出于傳遞更多信息之目的,不代表金鑰匙跨境贊同其觀點(diǎn)和立場(chǎng)。

轉(zhuǎn)載請(qǐng)注明,如有侵權(quán),聯(lián)系刪除。

本文鏈接:http://gantiao.com.cn/post/19531156.html

發(fā)布評(píng)論

您暫未設(shè)置收款碼

請(qǐng)?jiān)谥黝}配置——文章設(shè)置里上傳

掃描二維碼手機(jī)訪問(wèn)

文章目錄