waitpid() 是進程回收子進程狀態的核心系統調用。配合 WNOHANG 選項可實現非阻塞輪詢,避免父進程卡死在 wait() 上。本文結合實測代碼與輸出,逐幀解析三種典型返回值(-1、0、>0)的含義與應用場景。
pid_t waitpid(pid_t pid, int *status, int options);
| 參數 | 說明 |
|---|---|
| pid | >0 等待特定 PID;-1 等待任意子進程;0 等待同組;<-1 等待組 ID |
| status | 輸出參數,配合 WIFEXITED/WEXITSTATUS 等宏解析 |
| options | WNOHANG 非阻塞;WUNTRACED 回收停止態;WCONTINUED 回收繼續態 |
| 返回值 | 含義 | 典型場景 |
|---|---|---|
| -1 | 出錯,errno 指示原因(ECHILD:無子進程) | 尚未 fork、或所有子進程已被回收 |
| 0 | 非阻塞模式下:有子進程但均未退出 | 子進程正在運行,父進程可繼續做其他事 |
| >0 | 成功回收,返回結束的子進程 PID | 子進程已退出,status 含退出碼/信號 |
#include
#include
#include
int main() {
pid_t pid;
int status;
// 1. 無子進程時調用
pid = waitpid(-1, &status, WNOHANG);
printf("1st waitpid: pid=%d, errno=%d\n", pid, errno); // 輸出 -1, ECHILD
// 2. fork 子進程,子進程睡眠 3 秒
if ((pid = fork()) == 0) {
sleep(3);
_exit(42);
}
// 父進程立即非阻塞輪詢
pid = waitpid(-1, &status, WNOHANG);
printf("2nd waitpid: pid=%d\n", pid); // 輸出 0(子進程未退出)
// 父進程睡眠 4 秒後再試
sleep(4);
pid = waitpid(-1, &status, WNOHANG);
printf("3rd waitpid: pid=%d, status=%d\n", pid, WEXITSTATUS(status)); // 輸出子進程 PID, 42
return 0;
}
1st waitpid: pid=-1, errno=10 (ECHILD) // 無子進程
2nd waitpid: pid=0 // 有子進程但未退出
3rd waitpid: pid=12345, status=42 // 成功回收
while (1) {
pid_t pid = waitpid(-1, &status, WNOHANG);
if (pid > 0) handle_child_exit(pid, status);
else if (pid == 0) {
// 子進程仍在跑,處理網路/定時器等其他事件
do_other_work();
} else { // -1
if (errno == ECHILD) break; // 沒孩子了
perror("waitpid");
}
}
void sigchld_handler(int sig) {
int status;
while (waitpid(-1, &status, WNOHANG) > 0) {
// 循環回收所有已退出子進程
}
}
signal(SIGCHLD, sigchld_handler); // 或 sigaction 設置 SA_RESTART|SA_NOCLDSTOP
優勢:無需輪詢,子進程退出即時通知,配合 WNOHANG 循環回收防止信號合併丟失。
waitpid,多子進程近乎同時退出時會漏回收(信號合併)。wait 導致子進程退出後長期佔用 task_struct(PID 洩漏)。waitpid(-1, &status, WNOHANG) 返回值三部曲:
-1 (ECHILD) → 沒孩子;
0 → 有孩子但還活著;
>0 → 孩子已歸西,拿走屍體(PID+狀態)。
生產環境首選 SIGCHLD + WNOHANG 循環回收,兼顧即時性與健壯性。
Linux 網卡啟動失敗「Device not present」排查:MAC 地址綁定修復實戰
Linux 磁碟掛載完整指南:fdisk (MBR) 與 parted (GPT/大於 2TB) 實戰
內網穿透實戰:以 VNC 實現 Linux/Unix 桌面遠端雙向控制
DIY Linux 下拼音五筆融合輸入法:SCIM 碼表整合全記錄
YUV 格式深度解析:採樣制、存儲佈局與 420/422 互轉算法
Windows 7 與 Fedora 雙系統安裝:保護 MBR、使用 EasyBCD 管理開機選單完整教學