国产成人精品18p,天天干成人网,无码专区狠狠躁天天躁,美女脱精光隐私扒开免费观看

Centos進(jìn)程狀態(tài)怎么看

發(fā)布時(shí)間:2021-08-17 12:35 來(lái)源:億速云 閱讀:0 作者:chen 欄目: 服務(wù)器 歡迎投稿:712375056

本篇內容介紹了“Centos進(jìn)程狀態(tài)怎么看”的有關(guān)知識,在實(shí)際案例的操作過(guò)程中,不少人都會(huì )遇到這樣的困境,接下來(lái)就讓小編帶領(lǐng)大家學(xué)習一下如何處理這些情況吧!希望大家仔細閱讀,能夠學(xué)有所成!

眾所周知,現在的分時(shí)操作系統能夠在一個(gè)CPU上運行多個(gè)程序,讓這些程序表面上看起來(lái)是在同時(shí)運行的。linux就是這樣的一個(gè)操作系統。

在linux系統中,每個(gè)被運行的程序實(shí)例對應一個(gè)或多個(gè)進(jìn)程。linux內核需要對這些進(jìn)程進(jìn)行管理,以使它們在系統中“同時(shí)”運行。linux內核對進(jìn)程的這種管理分兩個(gè)方面:進(jìn)程狀態(tài)管理,和進(jìn)程調度。

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

在linux下,通過(guò)ps命令我們能夠查看到系統中存在的進(jìn)程,以及它們的狀態(tài):

R (TASK_RUNNING),可執行狀態(tài)。

只有在該狀態(tài)的進(jìn)程才可能在CPU上運行。而同一時(shí)刻可能有多個(gè)進(jìn)程處于可執行狀態(tài),這些進(jìn)程的task_struct結構(進(jìn)程控制塊)被放入對應CPU的可執行隊列中(一個(gè)進(jìn)程最多只能出現在一個(gè)CPU的可執行隊列中)。進(jìn)程調度器的任務(wù)就是從各個(gè)CPU的可執行隊列中分別選擇一個(gè)進(jìn)程在該CPU上運行。

只要可執行隊列不為空,其對應的CPU就不能偷懶,就要執行其中某個(gè)進(jìn)程。一般稱(chēng)此時(shí)的CPU“忙碌”。對應的,CPU“空閑”就是指其對應的可執行隊列為空,以致于CPU無(wú)事可做。

有人問(wèn),為什么死循環(huán)程序會(huì )導致CPU占用高呢?因為死循環(huán)程序基本上總是處于TASK_RUNNING狀態(tài)(進(jìn)程處于可執行隊列中)。除非一些非常極端情況(比如系統內存嚴重緊缺,導致進(jìn)程的某些需要使用的頁(yè)面被換出,并且在頁(yè)面需要換入時(shí)又無(wú)法分配到內存……),否則這個(gè)進(jìn)程不會(huì )睡眠。所以CPU的可執行隊列總是不為空(至少有這么個(gè)進(jìn)程存在),CPU也就不會(huì )“空閑”。

很多操作系統教科書(shū)將正在CPU上執行的進(jìn)程定義為RUNNING狀態(tài)、而將可執行但是尚未被調度執行的進(jìn)程定義為READY狀態(tài),這兩種狀態(tài)在linux下統一為 TASK_RUNNING狀態(tài)。

S (TASK_INTERRUPTIBLE),可中斷的睡眠狀態(tài)。

處于這個(gè)狀態(tài)的進(jìn)程因為等待某某事件的發(fā)生(比如等待socket連接、等待信號量),而被掛起。這些進(jìn)程的task_struct結構被放入對應事件的等待隊列中。當這些事件發(fā)生時(shí)(由外部中斷觸發(fā)、或由其他進(jìn)程觸發(fā)),對應的等待隊列中的一個(gè)或多個(gè)進(jìn)程將被喚醒。

通過(guò)ps命令我們會(huì )看到,一般情況下,進(jìn)程列表中的絕大多數進(jìn)程都處于TASK_INTERRUPTIBLE狀態(tài)(除非機器的負載很高)。畢竟CPU就這么一兩個(gè),進(jìn)程動(dòng)輒幾十上百個(gè),如果不是絕大多數進(jìn)程都在睡眠,CPU又怎么響應得過(guò)來(lái)。

D (TASK_UNINTERRUPTIBLE),不可中斷的睡眠狀態(tài)。

與TASK_INTERRUPTIBLE狀態(tài)類(lèi)似,進(jìn)程處于睡眠狀態(tài),但是此刻進(jìn)程是不可中斷的。不可中斷,指的并不是CPU不響應外部硬件的中斷,而是指進(jìn)程不響應異步信號。

絕大多數情況下,進(jìn)程處在睡眠狀態(tài)時(shí),總是應該能夠響應異步信號的。否則你將驚奇的發(fā)現,kill -9竟然殺不死一個(gè)正在睡眠的進(jìn)程了!于是我們也很好理解,為什么ps命令看到的進(jìn)程幾乎不會(huì )出現TASK_UNINTERRUPTIBLE狀態(tài),而總是TASK_INTERRUPTIBLE狀態(tài)。

而TASK_UNINTERRUPTIBLE狀態(tài)存在的意義就在于,內核的某些處理流程是不能被打斷的。如果響應異步信號,程序的執行流程中就會(huì )被插入一段用于處理異步信號的流程(這個(gè)插入的流程可能只存在于內核態(tài),也可能延伸到用戶(hù)態(tài)),于是原有的流程就被中斷了(參見(jiàn)《linux異步信號handle淺析》)。

在進(jìn)程對某些硬件進(jìn)行操作時(shí)(比如進(jìn)程調用read系統調用對某個(gè)設備文件進(jìn)行讀操作,而read系統調用最終執行到對應設備驅動(dòng)的代碼,并與對應的物理設備進(jìn)行交互),可能需要使用TASK_UNINTERRUPTIBLE狀態(tài)對進(jìn)程進(jìn)行保護,以避免進(jìn)程與設備交互的過(guò)程被打斷,造成設備陷入不可控的狀態(tài)。(比如read系統調用觸發(fā)了一次磁盤(pán)到用戶(hù)空間的內存的DMA,如果DMA進(jìn)行過(guò)程中,進(jìn)程由于響應信號而退出了,那么DMA正在訪(fǎng)問(wèn)的內存可能就要被釋放了。)這種情況下的TASK_UNINTERRUPTIBLE狀態(tài)總是非常短暫的,通過(guò)ps命令基本上不可能捕捉到。

linux系統中也存在容易捕捉的TASK_UNINTERRUPTIBLE狀態(tài)。執行vfork系統調用后,父進(jìn)程將進(jìn)入TASK_UNINTERRUPTIBLE狀態(tài),直到子進(jìn)程調用exit或exec。

通過(guò)下面的代碼就能得到處于TASK_UNINTERRUPTIBLE狀態(tài)的進(jìn)程:

#include <unistd.h>

void main() {

if (!vfork()) sleep(100);

}

編譯運行,然后ps一下:

kouu@kouu-one:~/test$ ps -ax | grep a\.out

4371 pts/0    D+     0:00 ./a.out

4372 pts/0    S+     0:00 ./a.out

4374 pts/1    S+     0:00 grep a.out

然后我們可以試驗一下TASK_UNINTERRUPTIBLE狀態(tài)的威力。不管kill還是kill -9,這個(gè)TASK_UNINTERRUPTIBLE狀態(tài)的父進(jìn)程依然屹立不倒。

T (TASK_STOPPED or TASK_TRACED),暫停狀態(tài)或跟蹤狀態(tài)。

向進(jìn)程發(fā)送一個(gè)SIGSTOP信號,它就會(huì )因響應該信號而進(jìn)入TASK_STOPPED狀態(tài)(除非該進(jìn)程本身處于TASK_UNINTERRUPTIBLE狀態(tài)而不響應信號)。(SIGSTOP與SIGKILL信號一樣,是非常強制的。不允許用戶(hù)進(jìn)程通過(guò)signal系列的系統調用重新設置對應的信號處理函數。)

向進(jìn)程發(fā)送一個(gè)SIGCONT信號,可以讓其從TASK_STOPPED狀態(tài)恢復到TASK_RUNNING狀態(tài)。

當進(jìn)程正在被跟蹤時(shí),它處于TASK_TRACED這個(gè)特殊的狀態(tài)?!罢诒桓櫋敝傅氖沁M(jìn)程暫停下來(lái),等待跟蹤它的進(jìn)程對它進(jìn)行操作。比如在gdb中對被跟蹤的進(jìn)程下一個(gè)斷點(diǎn),進(jìn)程在斷點(diǎn)處停下來(lái)的時(shí)候就處于TASK_TRACED狀態(tài)。而在其他時(shí)候,被跟蹤的進(jìn)程還是處于前面提到的那些狀態(tài)。

對于進(jìn)程本身來(lái)說(shuō),TASK_STOPPED和TASK_TRACED狀態(tài)很類(lèi)似,都是表示進(jìn)程暫停下來(lái)。。

而TASK_TRACED狀態(tài)相當于在TASK_STOPPED之上多了一層保護,處于TASK_TRACED狀態(tài)的進(jìn)程不能響應SIGCONT信號而被喚醒。只能等到調試進(jìn)程通過(guò)ptrace系統調用執行PTRACE_CONT、PTRACE_DETACH等操作(通過(guò)ptrace系統調用的參數指定操作),或調試進(jìn)程退出,被調試的進(jìn)程才能恢復TASK_RUNNING狀態(tài)。

Z (TASK_DEAD - EXIT_ZOMBIE),退出狀態(tài),進(jìn)程成為僵尸進(jìn)程。

進(jìn)程在退出的過(guò)程中,處于TASK_DEAD狀態(tài)。

在這個(gè)退出過(guò)程中,進(jìn)程占有的所有資源將被回收,除了task_struct結構(以及少數資源)以外。于是進(jìn)程就只剩下task_struct這么個(gè)空殼,故稱(chēng)為僵尸。

之所以保留task_struct,是因為task_struct里面保存了進(jìn)程的退出碼、以及一些統計信息。而其父進(jìn)程很可能會(huì )關(guān)心這些信息。比如在shell中,$?變量就保存了最后一個(gè)退出的前臺進(jìn)程的退出碼,而這個(gè)退出碼往往被作為if語(yǔ)句的判斷條件。

當然,內核也可以將這些信息保存在別的地方,而將task_struct結構釋放掉,以節省一些空間。但是使用task_struct結構更為方便,因為在內核中已經(jīng)建立了從pid到task_struct查找關(guān)系,還有進(jìn)程間的父子關(guān)系。釋放掉task_struct,則需要建立一些新的數據結構,以便讓父進(jìn)程找到它的子進(jìn)程的退出信息。

父進(jìn)程可以通過(guò)wait系列的系統調用(如wait4、waitid)來(lái)等待某個(gè)或某些子進(jìn)程的退出,并獲取它的退出信息。然后wait系列的系統調用會(huì )順便將子進(jìn)程的尸體(task_struct)也釋放掉。

子進(jìn)程在退出的過(guò)程中,內核會(huì )給其父進(jìn)程發(fā)送一個(gè)信號,通知父進(jìn)程來(lái)“收尸”。這個(gè)信號默認是SIGCHLD,但是在通過(guò)clone系統調用創(chuàng )建子進(jìn)程時(shí),可以設置這個(gè)信號。

通過(guò)下面的代碼能夠制造一個(gè)EXIT_ZOMBIE狀態(tài)的進(jìn)程:

#include <unistd.h>

void main() {

if (fork())

while(1) sleep(100);

}

編譯運行,然后ps一下:

kouu@kouu-one:~/test$ ps -ax | grep a\.out

10410 pts/0    S+     0:00 ./a.out

10411 pts/0    Z+     0:00 [a.out] <defunct>

10413 pts/1    S+     0:00 grep a.out

只要父進(jìn)程不退出,這個(gè)僵尸狀態(tài)的子進(jìn)程就一直存在。那么如果父進(jìn)程退出了呢,誰(shuí)又來(lái)給子進(jìn)程“收尸”?

當進(jìn)程退出的時(shí)候,會(huì )將它的所有子進(jìn)程都托管給別的進(jìn)程(使之成為別的進(jìn)程的子進(jìn)程)。托管給誰(shuí)呢?可能是退出進(jìn)程所在進(jìn)程組的下一個(gè)進(jìn)程(如果存在的話(huà)),或者是1號進(jìn)程。所以每個(gè)進(jìn)程、每時(shí)每刻都有父進(jìn)程存在。除非它是1號進(jìn)程。

1號進(jìn)程,pid為1的進(jìn)程,又稱(chēng)init進(jìn)程。

linux系統啟動(dòng)后,第一個(gè)被創(chuàng )建的用戶(hù)態(tài)進(jìn)程就是init進(jìn)程。它有兩項使命:

1、執行系統初始化腳本,創(chuàng )建一系列的進(jìn)程(它們都是init進(jìn)程的子孫);

2、在一個(gè)死循環(huán)中等待其子進(jìn)程的退出事件,并調用waitid系統調用來(lái)完成“收尸”工作;

init進(jìn)程不會(huì )被暫停、也不會(huì )被殺死(這是由內核來(lái)保證的)。它在等待子進(jìn)程退出的過(guò)程中處于TASK_INTERRUPTIBLE狀態(tài),“收尸”過(guò)程中則處于TASK_RUNNING狀態(tài)。

 X(TASK_DEAD - EXIT_DEAD),退出狀態(tài),進(jìn)程即將被銷(xiāo)毀。

而進(jìn)程在退出過(guò)程中也可能不會(huì )保留它的task_struct。比如這個(gè)進(jìn)程是多線(xiàn)程程序中被detach過(guò)的進(jìn)程?;蛘吒高M(jìn)程通過(guò)設置SIGCHLD信號的handler為SIG_IGN,顯式的忽略了SIGCHLD信號。(這是posix的規定,盡管子進(jìn)程的退出信號可以被設置為SIGCHLD以外的其他信號。)

此時(shí),進(jìn)程將被置于EXIT_DEAD退出狀態(tài),這意味著(zhù)接下來(lái)的代碼立即就會(huì )將該進(jìn)程徹底釋放。所以EXIT_DEAD狀態(tài)是非常短暫的,幾乎不可能通過(guò)ps命令捕捉到。

進(jìn)程的初始狀態(tài)

進(jìn)程是通過(guò)fork系列的系統調用(fork、clone、vfork)來(lái)創(chuàng )建的,內核(或內核模塊)也可以通過(guò)kernel_thread函數創(chuàng )建內核進(jìn)程。這些創(chuàng )建子進(jìn)程的函數本質(zhì)上都完成了相同的功能&mdash;&mdash;將調用進(jìn)程復制一份,得到子進(jìn)程。(可以通過(guò)選項參數來(lái)決定各種資源是共享、還是私有。)

那么既然調用進(jìn)程處于TASK_RUNNING狀態(tài)(否則,它若不是正在運行,又怎么進(jìn)行調用?),則子進(jìn)程默認也處于TASK_RUNNING狀態(tài)。

另外,在系統調用調用clone和內核函數kernel_thread也接受CLONE_STOPPED選項,從而將子進(jìn)程的初始狀態(tài)置為 TASK_STOPPED。

進(jìn)程狀態(tài)變遷

進(jìn)程自創(chuàng )建以后,狀態(tài)可能發(fā)生一系列的變化,直到進(jìn)程退出。而盡管進(jìn)程狀態(tài)有好幾種,但是進(jìn)程狀態(tài)的變遷卻只有兩個(gè)方向&mdash;&mdash;從TASK_RUNNING狀態(tài)變?yōu)榉荰ASK_RUNNING狀態(tài)、或者從非TASK_RUNNING狀態(tài)變?yōu)門(mén)ASK_RUNNING狀態(tài)。

也就是說(shuō),如果給一個(gè)TASK_INTERRUPTIBLE狀態(tài)的進(jìn)程發(fā)送SIGKILL信號,這個(gè)進(jìn)程將先被喚醒(進(jìn)入TASK_RUNNING狀態(tài)),然后再響應SIGKILL信號而退出(變?yōu)門(mén)ASK_DEAD狀態(tài))。并不會(huì )從TASK_INTERRUPTIBLE狀態(tài)直接退出。

進(jìn)程從非TASK_RUNNING狀態(tài)變?yōu)門(mén)ASK_RUNNING狀態(tài),是由別的進(jìn)程(也可能是中斷處理程序)執行喚醒操作來(lái)實(shí)現的。執行喚醒的進(jìn)程設置被喚醒進(jìn)程的狀態(tài)為T(mén)ASK_RUNNING,然后將其task_struct結構加入到某個(gè)CPU的可執行隊列中。于是被喚醒的進(jìn)程將有機會(huì )被調度執行。

而進(jìn)程從TASK_RUNNING狀態(tài)變?yōu)榉荰ASK_RUNNING狀態(tài),則有兩種途徑:

1、響應信號而進(jìn)入TASK_STOPED狀態(tài)、或TASK_DEAD狀態(tài);

2、執行系統調用主動(dòng)進(jìn)入TASK_INTERRUPTIBLE狀態(tài)(如nanosleep系統調用)、或TASK_DEAD狀態(tài)(如exit系統調用);或由于執行系統調用需要的資源得不到滿(mǎn)足,而進(jìn)入TASK_INTERRUPTIBLE狀態(tài)或TASK_UNINTERRUPTIBLE狀態(tài)(如select系統調用)。

顯然,這兩種情況都只能發(fā)生在進(jìn)程正在CPU上執行的情況下。

免責聲明:本站發(fā)布的內容(圖片、視頻和文字)以原創(chuàng )、來(lái)自本網(wǎng)站內容采集于網(wǎng)絡(luò )互聯(lián)網(wǎng)轉載等其它媒體和分享為主,內容觀(guān)點(diǎn)不代表本網(wǎng)站立場(chǎng),如侵犯了原作者的版權,請告知一經(jīng)查實(shí),將立刻刪除涉嫌侵權內容,聯(lián)系我們QQ:712375056,同時(shí)歡迎投稿傳遞力量。

女人高潮抽搐喷液30分钟视频| 天天爽夜夜爽人人爽从早干到睌| 色吊丝中文字幕| 国产办公室秘书无码精品| 久久久久久久综合综合狠狠| 太紧了夹得我的巴好爽|