1. 程式人生 > >關於linux環境下訊號SIGCHLD的排隊機制

關於linux環境下訊號SIGCHLD的排隊機制

一直對這個問題沒有深入的思考過。最近由於專案的需要終於弄清了這個問題。
以下文字是抄襲+理解+估計:

在linux系統中,子程序的正常/異常終止都會給父程序傳送SIGCHLD的訊號,當父程序接收到子程序(第一個)訊號進行wait()或waitpid()時,會遮蔽掉下一個的SIGCHLD訊號,實際的效果就是在訊號處理函式返回前不會重入。
那麼當父程序在執行訊號處理函式時,又有子程序(第二個)退出,那麼訊號會被阻塞並等待處理,假如(第三個)又來了,那麼它是被拋棄的,後續的都會拋棄。。。
所以說訊號是阻塞但不排隊的。

如果子程序可能會同時退出,那麼父程序需要這樣來處理以防止殭屍程序的出現:
pid_t childpid;
while( (childpid = waitpid(-1, NULL, WNOHANG)) > 0)
{
 ...
}

這樣,即使出現子程序同時退出的情況,SIGCHLD的訊號被拋棄也沒有關係。waitpid會收集所有當前已終止(實際就是處於殭屍狀態)的子程序,直到沒有這樣的程序狀態需要收集(返回0)。