亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 系統 > CentOS > 正文

Centos進程狀態詳解

2020-06-21 12:50:11
字體:
來源:轉載
供稿:網友

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

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

進程狀態

在linux下,通過ps命令我們能夠查看到系統中存在的進程,以及它們的狀態:

R (TASK_RUNNING),可執行狀態。

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

只要可執行隊列不為空,其對應的CPU就不能偷懶,就要執行其中某個進程。一般稱此時的CPU“忙碌”。對應的,CPU“空閑”就是指其對應的可執行隊列為空,以致于CPU無事可做。

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

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

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

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

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

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

與TASK_INTERRUPTIBLE狀態類似,進程處于睡眠狀態,但是此刻進程是不可中斷的。不可中斷,指的并不是CPU不響應外部硬件的中斷,而是指進程不響應異步信號。

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

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

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

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

通過下面的代碼就能得到處于TASK_UNINTERRUPTIBLE狀態的進程:

#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狀態的威力。不管kill還是kill -9,這個TASK_UNINTERRUPTIBLE狀態的父進程依然屹立不倒。

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

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

向進程發送一個SIGCONT信號,可以讓其從TASK_STOPPED狀態恢復到TASK_RUNNING狀態。

當進程正在被跟蹤時,它處于TASK_TRACED這個特殊的狀態。“正在被跟蹤”指的是進程暫停下來,等待跟蹤它的進程對它進行操作。比如在gdb中對被跟蹤的進程下一個斷點,進程在斷點處停下來的時候就處于TASK_TRACED狀態。而在其他時候,被跟蹤的進程還是處于前面提到的那些狀態。

對于進程本身來說,TASK_STOPPED和TASK_TRACED狀態很類似,都是表示進程暫停下來。。

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

Z (TASK_DEAD - EXIT_ZOMBIE),退出狀態,進程成為僵尸進程。

進程在退出的過程中,處于TASK_DEAD狀態。

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

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

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

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

子進程在退出的過程中,內核會給其父進程發送一個信號,通知父進程來“收尸”。這個信號默認是SIGCHLD,但是在通過clone系統調用創建子進程時,可以設置這個信號。

通過下面的代碼能夠制造一個EXIT_ZOMBIE狀態的進程:

#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

只要父進程不退出,這個僵尸狀態的子進程就一直存在。那么如果父進程退出了呢,誰又來給子進程“收尸”?

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

1號進程,pid為1的進程,又稱init進程。

linux系統啟動后,第一個被創建的用戶態進程就是init進程。它有兩項使命:

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

2、在一個死循環中等待其子進程的退出事件,并調用waitid系統調用來完成“收尸”工作;

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

 X(TASK_DEAD - EXIT_DEAD),退出狀態,進程即將被銷毀。

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

此時,進程將被置于EXIT_DEAD退出狀態,這意味著接下來的代碼立即就會將該進程徹底釋放。所以EXIT_DEAD狀態是非常短暫的,幾乎不可能通過ps命令捕捉到。

進程的初始狀態

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

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

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

進程狀態變遷

進程自創建以后,狀態可能發生一系列的變化,直到進程退出。而盡管進程狀態有好幾種,但是進程狀態的變遷卻只有兩個方向——從TASK_RUNNING狀態變為非TASK_RUNNING狀態、或者從非TASK_RUNNING狀態變為TASK_RUNNING狀態。

也就是說,如果給一個TASK_INTERRUPTIBLE狀態的進程發送SIGKILL信號,這個進程將先被喚醒(進入TASK_RUNNING狀態),然后再響應SIGKILL信號而退出(變為TASK_DEAD狀態)。并不會從TASK_INTERRUPTIBLE狀態直接退出。

進程從非TASK_RUNNING狀態變為TASK_RUNNING狀態,是由別的進程(也可能是中斷處理程序)執行喚醒操作來實現的。執行喚醒的進程設置被喚醒進程的狀態為TASK_RUNNING,然后將其task_struct結構加入到某個CPU的可執行隊列中。于是被喚醒的進程將有機會被調度執行。

而進程從TASK_RUNNING狀態變為非TASK_RUNNING狀態,則有兩種途徑:

1、響應信號而進入TASK_STOPED狀態、或TASK_DEAD狀態;

2、執行系統調用主動進入TASK_INTERRUPTIBLE狀態(如nanosleep系統調用)、或TASK_DEAD狀態(如exit系統調用);或由于執行系統調用需要的資源得不到滿足,而進入TASK_INTERRUPTIBLE狀態或TASK_UNINTERRUPTIBLE狀態(如select系統調用)。

顯然,這兩種情況都只能發生在進程正在CPU上執行的情況下。


發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
裸体女人亚洲精品一区| 91免费精品国偷自产在线| 俺也去精品视频在线观看| 国产亚洲精品久久久久久777| 日韩美女免费线视频| 俺去亚洲欧洲欧美日韩| 久久免费视频网站| 欧美一区三区三区高中清蜜桃| 国产亚洲激情视频在线| 在线播放国产一区二区三区| 日韩av电影中文字幕| 久久精品国产2020观看福利| 亚洲欧美激情精品一区二区| 国产一区二区三区久久精品| 精品香蕉一区二区三区| 亚洲国内精品在线| 最近2019年中文视频免费在线观看| yw.139尤物在线精品视频| 欧美性视频网站| 国产日韩在线一区| 在线观看日韩欧美| 日本精品久久久久久久| 欧美性高潮床叫视频| 中文字幕日韩精品有码视频| 亚洲国产欧美一区二区三区同亚洲| 日韩精品在线播放| 全色精品综合影院| 国产91精品黑色丝袜高跟鞋| 亚洲国产欧美久久| 成人免费大片黄在线播放| 国自产精品手机在线观看视频| 日韩欧美一区视频| 久久久久国产一区二区三区| 久久久久久久电影一区| 亚洲最新在线视频| 伊人男人综合视频网| 欧美电影免费观看电视剧大全| 成人中文字幕+乱码+中文字幕| 亚洲国产精彩中文乱码av| 午夜精品久久久久久久久久久久久| 国内外成人免费激情在线视频| 国产成人高潮免费观看精品| 97视频在线观看网址| 91美女福利视频高清| 亚洲第一页中文字幕| 亚洲aⅴ日韩av电影在线观看| 久久综合免费视频| 成人国内精品久久久久一区| 久久久综合av| 欧美精品www| 日韩av中文字幕在线免费观看| 久久久久久尹人网香蕉| 亚洲精选一区二区| 国产精品久久在线观看| 疯狂欧美牲乱大交777| 91最新在线免费观看| 亚洲激情成人网| 中文字幕日韩有码| 欧美二区乱c黑人| 国产精品欧美激情在线播放| 国产成人高潮免费观看精品| 亚洲网站在线看| 国产精品99久久久久久久久久久久| 国产成人精品最新| 欧美一区二区大胆人体摄影专业网站| 久久久久一本一区二区青青蜜月| 亚洲女人天堂视频| 日韩黄色在线免费观看| 久久99久久99精品免观看粉嫩| 欧美激情乱人伦一区| 欧美色另类天堂2015| 九九热在线精品视频| 国产精品久久激情| 91免费的视频在线播放| 欧美日韩不卡合集视频| 亚洲裸体xxxx| 久久久久国色av免费观看性色| 国产精品美女久久久久av超清| 国产欧美日韩免费| 国产在线视频91| 欧美日韩中文在线| 亚洲国产一区二区三区四区| 久久99国产综合精品女同| 国产成人综合av| 九九热精品视频国产| 久久久久久免费精品| 日韩在线精品视频| 国产精品爱啪在线线免费观看| 欧美高清一级大片| 欧美孕妇毛茸茸xxxx| 国产91精品网站| 国产精品一区久久久| 国产亚洲欧美日韩一区二区| 亚洲日本aⅴ片在线观看香蕉| 日韩av在线导航| 亚洲嫩模很污视频| 狠狠色噜噜狠狠狠狠97| 91黑丝高跟在线| 国产原创欧美精品| 欧美大肥婆大肥bbbbb| 亚洲少妇中文在线| 欧美在线一级视频| 久久天天躁夜夜躁狠狠躁2022| 久久久日本电影| 国产一区二区在线播放| 91精品国产综合久久香蕉最新版| 17婷婷久久www| 国产亚洲成精品久久| 国产精品视频一区二区三区四| 成人免费观看a| 在线观看欧美视频| 久久久女女女女999久久| 国产香蕉一区二区三区在线视频| 亚洲成av人片在线观看香蕉| 精品二区三区线观看| 亚洲大胆人体在线| 国产免费成人av| 日本精品视频在线| 69久久夜色精品国产69| 国产亚洲福利一区| 国产美女久久精品| 欧美一级黑人aaaaaaa做受| 国产精品久久久久久久久久久久| 日韩欧美亚洲一二三区| 欧美网站在线观看| 亚洲一级一级97网| 美女精品久久久| 综合国产在线视频| 91国产美女在线观看| 国产精品香蕉在线观看| 97成人超碰免| 最近中文字幕mv在线一区二区三区四区| 日韩成人av网| 色妞在线综合亚洲欧美| 国产情人节一区| 亚洲人成网在线播放| 国自产精品手机在线观看视频| 91成人在线视频| 成人av.网址在线网站| 欧美另类69精品久久久久9999| 日韩视频在线免费观看| 538国产精品一区二区在线| 亚洲国产美女久久久久| 久久久亚洲国产天美传媒修理工| 成人福利在线观看| 欧美日韩999| 国产精品一香蕉国产线看观看| 欧美成人在线影院| 国产成人精品免高潮费视频| 懂色av一区二区三区| 欧美老女人性生活| 韩日精品中文字幕| 亚洲国产精品大全| 国产精品网站大全| 97精品免费视频| 日本免费在线精品| 欧美一级视频在线观看| 日产日韩在线亚洲欧美| 欧美成人在线免费| 成人午夜黄色影院| 亚洲欧美另类中文字幕| 热门国产精品亚洲第一区在线| 日韩在线中文字幕| 日韩在线免费视频观看|