1、wait的工作原理
(1)子進程結束時,系統向其父進程發送SIGCHILD信號
(2)父進程調用wait函數後阻塞
(3)父進程被SIGCHILD信號喚醒,然後去回收殭屍子進程
(4)父子進程之間是異步的,SIGCHILD信號機制就是爲了解決父子進程之間的異步通信問題,讓父進程可以及時的去回收殭屍子進程
(5)若父進程沒有任何子進程則wait返回錯誤。
2、參數解讀
(1)wait的參數status。
- status用來返回子進程結束時的狀態,父進程通過wait得到status後就可以知道子進程的一些結束狀態信息。
(2)wait的返回值pid_t。
- 這個返回值就是本次wait回收的子進程的PID。當前進程有可能有多個子進程,wait函數阻塞直到其中一個子進程結束wait就會返回,wait的返回值就可以用來判斷到底是哪一個子進程本次被回收了。
(3)小結:wait主要是用來回收子進程資源,回收同時還可以得知被回收子進程的pid和退出狀態。
(4)WIFEXITED、 WIFSIGNALED、 WEXITSTATUS這幾個宏用來獲取子進程的退出狀態。
- WIFEXITED宏用來判斷子進程是否正常終止(return、exit、_exit退出)。
- WIFSIGNALED宏用來判斷子進程是否非正常終止(被信號所終止)。
- WEXITSTATUS宏用來得到正常終止情況下的進程返回值。
3、fork後wait回收編程實例
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
int main(void)
{
pid_t p1 = -1;
pid_t ret = -1;
int status = 0;
p1 = fork(); //返回2次
if(p1 == 0)
{
//這裏一定是子進程
printf("子進程,pid = %d.\n", getpid());
}
else if(p1 > 0)
{
//這裏一定是父進程
printf("parent.\n");
ret = wait(&status);
printf("子進程已經被回收,子進程pid = %d.\n", ret);
printf("子進程是否被正常回收: %d.\n", WIFEXITED(status));
}
else
{
//這裏一定是fork出錯了
perror("fork");
return -1;
}
return 0;
}
4、wait和waitpd差別
(1)基本功能一樣,都是用來回收子進程的
(2)waitpid可以回收指定PID的子進程
(3)waitpid可以阻塞或者非阻塞兩種工作模式。