1. 程式人生 > >Linux中waitpid()函式的用法

Linux中waitpid()函式的用法

大家知道,當用fork啟動一個新的子程序的時候,子程序就有了新的生命週期,並將在其自己的地址空間內獨立執行。但有的時候,我們希望知道某一個自己建立的子程序何時結束,從而方便父程序做一些處理動作。同樣的,在用ptrace去attach一個程序滯後,那個被attach的程序某種意義上說可以算作那個attach它程序的子程序,這種情況下,有時候就想知道被除錯的程序何時停止執行。

以上兩種情況下,都可以使用Linux中的waitpid()函式做到。先來看看waitpid函式的定義:

#include <sys/types.h> 
#include <sys/wait.h>
pid_t waitpid(pid_t pid,int *status,int options);
如果在呼叫waitpid()函式時,當指定等待的子程序已經停止執行或結束了,則waitpid()會立即返回;但是如果子程序還沒有停止執行或結束,則呼叫waitpid()函式的父程序則會被阻塞,暫停執行。

下面來解釋以下呼叫引數的含義:

1)pid_t pid

引數pid為欲等待的子程序識別碼,其具體含義如下:

引數值 說明
pid<-1 等待程序組號為pid絕對值的任何子程序。
pid=-1 等待任何子程序,此時的waitpid()函式就退化成了普通的wait()函式。
pid=0 等待程序組號與目前程序相同的任何子程序,也就是說任何和呼叫waitpid()函式的程序在同一個程序組的程序。
pid>0 等待程序號為pid的子程序。

2)int *status

這個引數將儲存子程序的狀態資訊,有了這個資訊父程序就可以瞭解子程序為什麼會推出,是正常推出還是出了什麼錯誤。如果status不是空指標,則狀態資訊將被寫入
器指向的位置。當然,如果不關心子程序為什麼推出的話,也可以傳入空指標。 Linux提供了一些非常有用的巨集來幫助解析這個狀態資訊,這些巨集都定義在sys/wait.h標頭檔案中。主要有以下幾個:
巨集 說明
WIFEXITED(status) 如果子程序正常結束,它就返回真;否則返回假。
WEXITSTATUS(status) 如果WIFEXITED(status)為真,則可以用該巨集取得子程序exit()返回的結束程式碼。
WIFSIGNALED(status) 如果子程序因為一個未捕獲的訊號而終止,它就返回真;否則返回假。
WTERMSIG(status) 如果WIFSIGNALED(status)為真,則可以用該巨集獲得導致子程序終止的訊號程式碼。
WIFSTOPPED(status) 如果當前子程序被暫停了,則返回真;否則返回假。
WSTOPSIG(status) 如果WIFSTOPPED(status)為真,則可以使用該巨集獲得導致子程序暫停的訊號程式碼。

3)int options

引數options提供了一些另外的選項來控制waitpid()函式的行為。如果不想使用這些選項,則可以把這個引數設為0。 主要使用的有以下兩個選項:
引數 說明
WNOHANG 如果pid指定的子程序沒有結束,則waitpid()函式立即返回0,而不是阻塞在這個函式上等待;如果結束了,則返回該子程序的程序號。
WUNTRACED 如果子程序進入暫停狀態,則馬上返回。
這些引數可以用“|”運算子連線起來使用。 如果waitpid()函式執行成功,則返回子程序的程序號;如果有錯誤發生,則返回-1,並且將失敗的原因存放在errno變數中。 失敗的原因主要有:沒有子程序(errno設定為ECHILD),呼叫被某個訊號中斷(errno設定為EINTR)或選項引數無效(errno設定為EINVAL) 如果像這樣呼叫waitpid函式:waitpid(-1, status, 0),這此時waitpid()函式就完全退化成了wait()函式。