進程式控制制之wait和waitpid函數

來源:互聯網
上載者:User

當一個進程正常或異常終止時,核心就向其父進程發送SIGCHLD訊號。因為子進程終止是個非同步事件(這可以在父進程啟動並執行任何時候發生),所以這種訊號也是核心向父進程發的非同步通知。父進程可以選擇忽略該訊號,或者提供一個該訊號發生時即被調用執行的函數(訊號處理常式)。對於這種訊號的系統預設動作是忽略它)。

調用wait或waitpid的進程可能會發生的情況:

  • 如果其所有子進程都還在運行,則阻塞。
  • 如果一個子進程已終止,正等待父進程擷取其終止狀態,則取得該子進程的終止狀態立即返回。
  • 如果它沒有任何子進程,則立即出錯返回。

如果進程由於接收到SIGCHLD訊號而調用wait,則可期望wait會立即返回。但是如果在任意時刻調用wait,則進程可能會阻塞。

#include <sys/wait.h> *- *statloc, -,若指定了WNOHANG選項且pid指定的子進程狀態沒有發生改變則返回0

這兩個函數的區別如下:

  • 在一個子進程終止前,wait使其調用者阻塞,而waitpid有一個選項,可使調用者不阻塞。
  • waitpid並不等待在其調用之後的第一個終止子進程,它有若干個選項,可以控制它所等待的進程。

如果一個子進程已經終止,並且是一個僵死進程,則wait立即返回並取得該子進程的狀態,否則wait使其調用者阻塞直到一個子進程終止。如果調用者阻塞而且它有多個子進程,則在其一個子進程終止時,wait就立即返回。因為wait返回終止子進程的進程ID,所以它總能瞭解是哪一個子進程終止了。

這兩個函數的參數statloc是一個整型指標。如果statloc不是一個null 指標,則終止進程的終止狀態就存放在它所指向的單元內。如果不關心終止狀態,則可將該參數指定為空白指標。

依據傳統,這兩個函數返回的整型狀態字是由實現定義的。其中某些位表示退出狀態(正常返回),其他位則指示訊號編號(異常返回),有一位指示是否產生了一個core檔案等。POSIX.1規定狀態用定義在<sys/wait.h>中的各個宏來查看。有四個互斥的宏可用來取得進程終止的原因,它們的名字都以WIF開始。基於這四個宏中哪一個值為真,就可選用其他宏(表8-1說明欄中底線標註的宏)來取得終止狀態、訊號編號等。這四個互斥的宏示於表8-1中。

表8-1 檢查wait和waitpid所返回的終止狀態的宏

宏

說明

         WIFEXITED(status)     若為正常終止子進程返回的狀態,則為真。對於這種情況可執行WEXITSTATUS(status),取子進程傳送給exit、_exit或_Exit參數的低8位
         WIFSIGNALED(status)    若為異常終止子進程返回的狀態,則為真(接到一個不捕捉的訊號)。對於這種情況,可執行WTERMSIG(status),取使子進程終止的訊號編號。另外,有些實現定義宏WCOREDUMP(status),若已產生終止進程的core檔案,則它返回真
        WIFSTOPPED(status)    若為當前暫停子進程的返回狀態,則為真。對於這種情況,可執行WSTOPSIG(status),取使子進程暫停訊號編號
        WIFCONTINUED(status)    若在作業控制暫停後已經繼續的子進程返回了狀態,則為真。(POSIX.1的XSI擴充;僅用於waitpid。)

 

程式清單8-3 列印exit狀態的說明

[root@localhost apue]# cat prog8-<sys/wait.h> ?  :                          

程式清單8-4 示範不同的exit值(調用prog8-3中的pr_exit函數)

[root@localhost apue]# cat prog8-<sys/wait.h> ((pid = fork()) <   (pid == );                         (wait(&status) != pid)                ((pid = fork()) <   (pid == )               (wait(&status) != pid)                ((pid = fork()) <   (pid == )              /= ;                     (wait(&status) != pid)       

運行該程式可得:

[root@localhost apue]# ./prog8-= = = 

不幸的是,沒有一種可移植的方法將WTERMSIG得到的訊號編號映射為說明性的名字。我們必須查看<signal.h>標頭檔才能知道SIGABRT的值是6,SIGFPE的值是8.

正如前面所述,如果一個進程有幾個子進程,那麼只要有一個子進程終止,wait就返回。如果要等待一個指定的進程終止(如果知道要等待進程的ID),那麼該如何做呢?POSIX.1定義了waitpid函數以提供這種功能(以及其他一些功能)。

對於waitpid函數中pid參數的作用解釋如下:

pid == –1   等待任一子進程。就這一方面而言,waitpid與wait等效。
pid > 0   等待其進程ID與pid相等的子進程。
pid == 0   等待其組ID等於調用進程組ID的任一子進程。
pid < –1   等待其組ID等於pid絕對值的任一子進程。

waitpid函數返回終止子進程的進程ID,並將該子進程的終止狀態存放在由status指向的儲存單元中。對於wait,其唯一的出錯是調用進程沒有子進程(函數調用被一個訊號中斷時,也可能返回另一種出錯)。但是對於waitpid,如果指定的進程或進程組不存在,或者參數pid指定的進程不是調用進程的子進程則都將出錯。

options參數使我們能進一步控制waitpid的操作。此參數可以是0,或者是表8-2中常量按位“或”運算的結果。

表8-2 waitpid的options常量

常量

說明

          WCONTINUED   若實現支援作業控制,那麼由pid指定的任一子進程在暫停後已經繼續,但其狀態尚未報告,則返回其狀態
          WNOHANG   若由pid指定的子進程並不是立即可用的,則waitpid不阻塞,此時其傳回值為0
          WUNTRACED   若某實現支援作業控制,而由pid指定的任一子進程已處於暫停狀態,並且其狀態自暫停以來還未報告過,則返回其狀態。WIFSTOPPED宏確定傳回值是否對應於一個暫停子進程

 

waitpid函數提供了wait函數沒有提供的三個功能:

(1)waitpid可等待一個特定的進程,而wait則返回任一終止子進程的狀態。

(2)waitpid提供了一個wait的非阻塞版本。有時使用者希望取得一個子進程的狀態,但不想阻塞。

(3)waitpid支援作業控制(利用WUNTRACED和WCONTINUED選項)。

如果一個進程fork一個子進程,但不要等待子進程終止,也不希望子進程處於僵死狀態直到父進程終止,實現這一要求的技巧是調用fork兩次。

程式清單8-5 調用fork兩次以避免僵死進程

[root@localhost apue]# cat prog8-<sys/wait.h> ((pid = fork()) <   (pid == )               ((pid = fork()) <   (pid > );                         (waitpid(pid, NULL, ) != pid)       

第二個子進程調用sleep以保證在列印父進程ID時第一個子進程已終止。在fork之後,父、子進程都可繼續執行,並且我們無法預知哪一個會先執行。在fork之後,如果不使第二個子進程休眠,那麼它可能比其父進程先執行,於是它列印的父進程ID將是建立它的父進程,而不是init進程(進程ID 1)。

執行結果:

[root@localhost apue]# ./prog8-= 

注意,當原先的進程(也就是exec本程式的進程)終止時,shell列印其提示符,這在第二個子進程列印其父進程ID之前。

本篇博文內容摘自《UNIX環境進階編程》(第二版),僅作個人學習記錄所用。關於本書可參考:http://www.apuebook.com/。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.