1.SIGCHLD簡介
SIGCHILD是指在一個進程終止或者停止時,將SIGCHILD信號發送給其父進程,按照系統默認將忽略此信號,如果父進程希望被告知其子系統的這種狀態,則應捕捉此信號。注意:SIGCLD信號與其長得非常相似。SIGCLD是系統V的一個信號名,其語義與名為SIGCHLD的BSD信號不同。POSIX.1則采用BSD的SIGCHLD信號。BSD的SIGCHLD信號語義與其他信號的語義想類似。子信號狀態改變后產生此信號,父進程需要調用一個wait函數以確定發生什么。
2.SIGCHLD發生的條件
1.子進程已終止 CLD_EXITED
2.子進程異常終止(無core) CLD_KILLED
3.子進程異常終止(有core) CLD_DUMPED
4.被跟蹤子進程以陷入 CLD_TRAPPED
5.子進程已停止 CLD_STOPED
6.停止的子進程已經繼續 CLD_CONTINUED
7.子進程處在停止態,接受到SIGCONT后喚醒時
3.SIGCHLD注意事項
- 當阻塞于某個慢系統調用的一個進程捕獲某個信號且響應信號處理函數返回時,該系統調用可能返回EINTR錯誤;
- 在一個進程終止或者停止時,將SIGCHLD信號發送給其父進程。按系統默認將忽略此信號。如果父進程希望被告知其子系統的這種狀態,則應捕捉此信號。信號的捕捉函數中通常調用wait函數以取得進程ID和其終止狀態。
- SIGCHLD的信號處理函數必須正確編寫,應使用waitpid函數來避免留下僵尸進程。
// 信號處理函數
void sig_handler(int signo)
{pid_t fpid = 0;std::vector< int > fpids;if(SIGCHLD == signo) {//如果一個進程中有多個子進程在執行,那么wait函數將阻塞到第一個子進程終止時為止。//如果有多個子進程終止而成為僵尸進程,那么wait只能處理一個。也就是說,信號處理函數沒能完全處理僵尸進程。while((fpid = waitpid(-1, NULL, WNOHANG)) > 0){fpids.push_back(fpid);}}if(master::instance()->reload_child(fpids) != error_ok) {log_error("reload child fail\n");}
}
參考:https://blog.csdn.net/u012877472/article/details/50165083
? ? ? ? ? ?https://blog.csdn.net/oguro/article/details/53857376