pid_t wait(int * statloc);
pid_t waitpid(pid_t pid, int *statloc, int options);
兩 個函數都返回兩個值:函數的傳回值和終止的子進程ID,而子進程終止的狀態則是通過statloc指標返回的。wait&waitpid的區別是顯而易見 的,wait等待第一個終止的子進程,而waitpid則可以指定等待特定的子進程。這樣的區別可能會在下面這種情況時表現得更加明顯:當同時有5個客戶 連上伺服器,也就是說有五個子進程分別對應了5個客戶,此時,五個客戶幾乎在同時請求終止,這樣一來,幾乎同時,五個FIN發向伺服器,同樣的,五個 SIGCHLD訊號到達伺服器,然而,UNIX的訊號往往是不會排隊的,顯然這樣一來,訊號處理函數將只會執行一次,殘留剩餘四個子進程作為殭屍進程駐留 在核心空間。此時,正確的解決辦法是利用waitpid(-1, &stat, WNOHANG)防止留下殭屍進程。其中的pid為-1表明等待任一個終止的子進程,而WNOHANG選擇項通知核心在沒有已終止進程項時不要阻塞。
對於w a i t p i d的p i d參數的解釋與其值有關:
• pid == -1 等待任一子進程。於是在這一功能方面w a i t p i d與w a i t等效。
• pid > 0 等待其進程I D與p i d相等的子進程。
• pid == 0 等待其組I D等於調用進程的組I D的任一子進程。
• pid < -1 等待其組I D等於p i d的絕對值的任一子進程。
w a i t p i d返回終止子進程的進程I D,而該子進程的終止狀態則通過s t a t l o c返回。對於w a i t,其唯一的出錯是調用進程沒有子進程(函數調用被一個訊號中斷時,也可能返回另一種出錯。但是對於w a i t p i d,如果指定的進程或進程組不存在,或者調用進程沒有子進程都能出錯。
當一個進程正常或異常終止時,核心就向其父進程發送S I G C H L D訊號。因為子進程終止是個非同步事件(這可以在父進程啟動並執行任何時候發生),所以這種訊號也是核心向父進程發的非同步通知。父進程可以忽略該訊號,或者提供 一個該訊號發生時即被調用執行的函數(訊號處理常式)。對於這種訊號的系統預設動作是忽略它。調用w a i t或w a i t p i d的進程可能會:
• 阻塞(如果其所有子進程都還在運行)。
• 帶子進程的終止狀態立即返回(如果一個子進程已終止,正等待父進程存取其終止狀態)。
• 出錯立即返回(如果它沒有任何子進程)。
如果進程由於接收到S I G C H L D訊號而調用w a i t,則可期望w a i t會立即返回。但是如果在一
個任一時刻調用w a i t,則進程可能會阻塞。
例子:
void sig_chld(int signo)
{
int stat;
pid_t pid;
pid = waitpid(-1, &stat, WNOHANG);
printf("SIGCHLD: child pid=%d\n",(int)pid);
}
void main()
{
//....
signal(SIGCHLD, HandleChild);
//....
}