標籤:進程狀態 變遷
本小結主要總結,Linux下進程的幾種狀態及其間的相互轉換。
一、Linux進程的幾種狀態
1、Linux進程狀態:R (TASK_RUNNING),可執行狀態
Linux下處於運行狀態和就緒狀態的進程,統稱為R狀態,一個進程只有處於該狀態才有可能被CPU執行。同一時刻可以有多個進程處於該狀態,處於這些狀態的進程都將會被裝入一個可執行檔隊列中,系統中進程調度器的作用就是從這個可執行檔隊列中選擇一個進程進行執行。
2、Linux進程狀態:S (TASK_INTERRUPTIBLE),可中斷的睡眠狀態
Linux中絕大多數的進程都是處於這個狀態,處於這個狀態的進程是可中斷的,比如使用kill發訊號讓進程退出。一個進程處於該狀態往往是由於進程需要等待某些資源進而被掛起,這些資源可能是訊號量、socket、io等,所有被掛起的進程也會被放入相應的隊列中,當其所要等待的資源到達時,這些進程將會被喚醒。
3、Linux進程狀態:D (TASK_UNINTERRUPTIBLE),不可中斷的睡眠狀態
顯而易見,處於該狀態的進程是不能被中斷的,這種型的進程是不接受非同步通訊產生的訊號的,在Linux中這是系統對重要的“事件”的進程提供的一種保護,以避免中斷對系統造成不可挽回的操作。
4、Linux進程狀態:T (TASK_STOPPED or TASK_TRACED),暫停狀態或跟蹤狀態
在實際應用中,有可能需要給正在啟動並執行進程發送訊號,讓其處在暫停狀態,以便完成調試、跟蹤的需求。
5、Linux進程狀態:Z (TASK_DEAD – EXIT_ZOMBIE),退出狀態,進程成為殭屍進程
父進程建立的子進程後,父子進程將會各自完成自身的任務,子進程在運行完成後將清除本身的資源,並由父進程完成回收,但在子進程還沒運行完成,父進程便已處於退出,那麼這些還在啟動並執行進程將變成退出狀態,即變成殭屍進程,由於系統中還存在一個Init進程(整個Linux的鼻祖進程),系統存在的所有殭屍進程都過繼給鼻祖進程,由其來完成回收過程。
6、Linux進程狀態:X (TASK_DEAD – EXIT_DEAD),退出狀態,進程即將被銷毀。
而進程在退出過程中也可能不會保留它的task_struct。比如這個進程是多線程程式中被detach過的進程,或者父進程通過設定SIGCHLD訊號的handler為SIG_IGN,顯式的忽略了SIGCHLD訊號。(這是posix的規定,儘管子進程的退出訊號可以被設定為SIGCHLD以外的其他訊號。)此時,進程將被置於EXIT_DEAD退出狀態,這意味著接下來的代碼立即就會將該進程徹底釋放。所以EXIT_DEAD狀態是非常短暫的,幾乎不可能通過ps命令捕捉到。
在Linux系統中,使用ps aux 命令,我們很容易查看到系統進程的狀態,如:
[[email protected] ~]$ ps aux
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
root 1 0.0 0.1 2900 1440 ? Ss 22:28 0:01 /sbin/init
root 2 0.0 0.0 0 0 ? S 22:28 0:00 [kthreadd]
root 3 0.0 0.0 0 0 ? S 22:28 0:00 [migration/0]
root 4 0.0 0.0 0 0 ? S 22:28 0:00 [ksoftirqd/0]
root 5 0.0 0.0 0 0 ? S 22:28 0:00 [migration/0]
root 6 0.0 0.0 0 0 ? S 22:28 0:00 [watchdog/0]
root 7 0.0 0.0 0 0 ? S 22:28 0:00 [events/0]
root 8 0.0 0.0 0 0 ? S 22:28 0:00 [cgroup]
root 9 0.0 0.0 0 0 ? S 22:28 0:00 [khelper]
root 10 0.0 0.0 0 0 ? S 22:28 0:00 [netns]
root 11 0.0 0.0 0 0 ? S 22:28 0:00 [async/mgr]
root 12 0.0 0.0 0 0 ? S 22:28 0:00 [pm]
root 13 0.0 0.0 0 0 ? S 22:28 0:00 [sync_supers]
其中的User表示運行系統的使用者標識,Pid是當前進程的進程號,%Cpu表示該進程所佔用的Cpu資源,%Mem表示該進程所使用的記憶體資源,VSZ表示進程的虛擬大小,RSS進程駐留集的大小,可以理解為記憶體中頁的數量,TTY表示控制終端的ID,STRAT–這個很簡單,就是該進程啟動的時間,TIME–進程已經消耗的CPU時間,注意是消耗CPU的時間;COMMOND–命令的名稱和參數;STAT–也就是當前進程的狀態,其中S-睡眠,s-表示該進程是會話的先導進程,N-表示進程擁有比普通優先順序更低的優先順序,R-正在運行,D-短期等待,Z-僵死進程,T-被跟蹤或者被停止等等。
二、Linux進程狀態間的相互轉換
進程自建立以後,狀態可能發生一系列的變化,直到進程退出。而儘管進程狀態有好幾種,但是進程狀態的變遷卻只有兩個方向——從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系統調用)。
本文出自 “簡單新生活” 部落格,請務必保留此出處http://857768.blog.51cto.com/847768/1661056
Linux 進程基礎(二)