殭屍程序: 子程序退出,父程序沒有**子程序資源(pcb),則子程序變成殭屍程序
孤兒程序: 父程序先於子程序結束,則子程序成為孤兒程序,子程序的父程序成為1號程序init程序,稱為init程序領養孤兒程序
#include
#include
pid_t wait(int
*status);
pid_t waitpid(pid_t pid, int
*status, int options);
乙個程序在終止時會關閉所有檔案描述符,釋放在使用者空間分配的記憶體,但它的pcb還保留著,核心在其中儲存了一些資訊:如果是正常終止則儲存著退出狀態,如果是異常終止則儲存著導致該程序終止的訊號是哪個。這個程序的父程序可以呼叫wait或waitpid獲取這些資訊,然後徹底清除掉這個程序。我們知道乙個程序的退出狀態可以在shell中用特殊變數$?檢視,因為shell是它的父程序,當它終止時shell呼叫wait或waitpid得到它的退出狀態同時徹底清除掉這個程序。
如果乙個程序已經終止,但是它的父程序尚未呼叫wait或waitpid對它進行清理,這時的程序狀態稱為殭屍(zombie)程序。任何程序在剛終止時都是殭屍程序,正常情況下,殭屍程序都立刻被父程序清理了,為了觀察到殭屍程序,我們自己寫乙個不正常的程式,父程序fork出子程序,子程序終止,而父程序既不終止也不呼叫wait清理子程序:
#include
#include
int main(void)
if(pid>0)
/* child */
return
0;}
檢視程序:
cat 2751
99.2
0.02008
284 pts/1 r+ 23:46
0:16 ./fork
cat 2752
0.00.0
00 pts/1 z+ 23:46
0:00 [fork]
可以看到子程序的狀態已經變成z+即殭屍態了。
wait/waitpid若呼叫成功則返回清理掉的子程序id,若呼叫出錯則返回-1。父程序呼叫wait或waitpid時可能會:
這兩個函式的區別是:
如果父程序的所有子程序都還在執行,呼叫wait將使父程序阻塞,而呼叫waitpid時如果在options引數中指定wnohang可以使父程序不阻塞而立即返回0。
wait等待第乙個終止的子程序,而waitpid可以通過pid引數指定等待哪乙個子程序。可見,呼叫wait和waitpid不僅可以獲得子程序的終止資訊,還可以使父程序阻塞等待子程序終止,起到程序間同步的作用。如果引數status不是空指標,則子程序的終止資訊通過這個引數傳出,如果只是為了同步而不關心子程序的終止資訊,可以將status引數指定為null。
例 waitpid
#include
#include
#include
#include
#include
int main(void)
if (pid == 0)
exit(3);
} else
return
0;}
結果:
this is
the child
this is
the child
this is
the child
this is
the child
this is
the child
this is
the child
this is
the child
this is
the child
child terminated abnormally, signal 9
...this is
the child
this is
the child
this is
the child
child exited with code 3
waitpid pid值的4種情況:
用於檢查wait和waitpid兩個函式返回終止狀態的巨集:
這兩個函式返回的子程序狀態都儲存在statloc指標中, 用以下3個巨集可以檢查該狀態:
wifsignaled(status): 若為異常終止, 則為真. 此時可執行
wifstopped(status): 若為當前暫停子程序, 則為真. 此時可執行
wait waitpid函式獲取狀態的使用
wifexited wstatus 如果子項正常終止 即通過呼叫exit 3 或 exit 2 或從main 返回 則返回true。wexitstatus wstatus 返回子項的退出狀態。它由狀態引數的最低有效8位組成,該狀態引數的子級是在呼叫exit 3 或 exit 2 時指定的,或者是ma...
程序之wait waitpid使用
上個部落格講了如何使用fork簡單的建立乙個新的程序,本篇文章將講下如何避免殭屍程序的產生,殭屍程序的產生就是因為子程序退出時沒有父程序替它 收屍 即沒有獲取子程序的狀態資訊,一般我們可以使用wait或者waitpid函式來進行處理 下面的 示例演示了子程序如何成為殭屍程序的過程 include i...
殭屍程序 wait waitpid
如果其所有子程序都在執行,則阻塞。如果乙個子程序已經終止,正在等待的父程序獲取到終止狀態,則取得該子程序的終止狀態立即返回。如果他沒有任何子程序,則立即出錯返回。void sig chld int signo pid 0時,只等待程序id等於pid的子程序,不管其它已經有多少子程序執行結束退出了,只...