Process
為什麼waitpid系統呼叫只能用於子程序?
手冊頁
wait(2)
指出,如果指定程序不是呼叫程序的子程序,則waitpid
係統呼叫將返回錯誤。ECHILD
為什麼是這樣?等待非子程序會產生某種安全問題嗎?是否有技術原因導致在非子程序上實現等待會很困難或不可能?
因為如何
waitpid
運作。在 POSIX 系統上,當一個子程序死亡時,一個信號 (SIGCHLD) 被傳遞給父程序。在高級別上,waitpid
所做的只是阻塞,直到為指定的程序(或程序之一)傳遞 SIGCHLD 信號。您不能等待任意程序,因為 SIGCHLD 信號永遠不會為它們傳遞。
godlygeek 的回答有助於理解系統的工作原理,但隨後不可避免的問題是:
如何確定一個程序是否已經消失?
在另一個程序組或會話中等待程序的正確方法是使用
kill()
. 顯然,這是一個不直覺的答案。您不能使用wait
函式係列,因為 SIGCHILD 信號永遠不會傳遞給您的程序,也無法獲得狀態程式碼。kill()
但是,可以通過傳入 0 以發送信號來告訴您特定程序何時消失,這只是檢查是否可以將信號發送到程序。的返回值kill()
很複雜,但可以歸結為:值 0 表示程序處於活動狀態並且會接受來自您的程序的信號,而值 -1 和 errno EPERM 表示程序處於活動狀態但不接受來自您的程序的信號過程。一些範例 C 程式碼每秒檢查一次以查看任意程序是否已消失:
int res = kill(pid, 0); while (res == 0 || (res < 0 && errno == EPERM)) { sleep(1); res = kill(pid, 0); }
您可以類似地使用以下
kill
命令進行試驗:kill -0 <pid>
這會將 pid 和 0 傳遞給
kill()
. 有些 shell 有一個內置的kill
,所以它比啟動一個新程序(例如 )要高效得多ps
。