亚洲韩日午夜视频,欧美日韩在线精品一区二区三区,韩国超清无码一区二区三区,亚洲国产成人影院播放,久草新在线,在线看片AV色

您好,歡迎來到思海網絡,我們將竭誠為您提供優質的服務! 誠征網絡推廣 | 網站備案 | 幫助中心 | 軟件下載 | 購買流程 | 付款方式 | 聯系我們 [ 會員登錄/注冊 ]
促銷推廣
客服中心
業務咨詢
有事點擊這里…  531199185
有事點擊這里…  61352289
點擊這里給我發消息  81721488
有事點擊這里…  376585780
有事點擊這里…  872642803
有事點擊這里…  459248018
有事點擊這里…  61352288
有事點擊這里…  380791050
技術支持
有事點擊這里…  714236853
有事點擊這里…  719304487
有事點擊這里…  1208894568
有事點擊這里…  61352289
在線客服
有事點擊這里…  531199185
有事點擊這里…  61352288
有事點擊這里…  983054746
有事點擊這里…  893984210
當前位置:首頁 >> 技術文章 >> 文章瀏覽
技術文章

Centos進程狀態詳解

添加時間:2019-7-4 14:43:22  添加: 思海網絡 
眾所周知,現在的分時操作系統能夠在一個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過的進程。或者父進程通過設置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上執行的情況下。


關鍵字:Centos、進程狀態、CPU
分享到:

頂部 】 【 關閉
版權所有:佛山思海電腦網絡有限公司 ©1998-2024 All Rights Reserved.
聯系電話:(0757)22630313、22633833
中華人民共和國增值電信業務經營許可證: 粵B1.B2-20030321 備案號:粵B2-20030321-1
網站公安備案編號:44060602000007 交互式欄目專項備案編號:200303DD003  
察察 工商 網安 舉報有獎  警警  手機打開網站