[英]`waitpid()' always returns -1
我正在執行以下代碼,對waitpid()
的調用始終返回-1
,因此下面的代碼以無限循環結尾。 如果我將WNOHANG
替換為0
則該呼叫有效。
void execute(cmdLine* pCmdLine) {
int status = 0;
pid_t pid = fork();
if(pid == 0) {
if(execvp(pCmdLine->arguments[0], pCmdLine->arguments) == -1) {
if(strcmp(pCmdLine->arguments[0], "cd") != 0) {
perror("execute failed\n");
}
_exit(1);
}
} else {
if(pCmdLine->blocking == 1) {
waitpid(pid, &status, 0);
}
while(waitpid(pid, &status, WNOHANG) == -1) {
printf("still -1\n");
}
}
}
}
好吧,您誤解了wait
系統調用的工作方式。
與malloc/free
,每個fork()
進程只能成功等待一次waitpid()
,因此,如果您要等待子代的退出代碼,則while
循環永遠不需要,您必須調用它只有一次。 在您的情況下,等待只會返回-1
,這有兩個原因:
fork()
沒有成功,因此您正在等待無效的pid
。 確實,您應該為pid == -1
調用wait()
,這是無效的。 如果您使用wait()
並且沒有等待的過程(如果pid
變量的值為正數,但是已經使用過wait()
子過程,您也會得到-1
),那么您會從任何wait()
系列系統調用。 UN * X系統中的僵屍進程的任務就是這樣,以確保對已完成的子進程的wait()
仍然有效,並且調用進程獲取該子進程在exit()
上發出的退出代碼。 您明確地說您不會等待該過程完成。 應該清楚的是,如果您不打算等待進程終止,那么這就是使用WNOHANG
參數執行的操作,那么子進程可能仍在運行(這是您的情況)並且尚未完成exit()
syscall。 如果子進程已經完成,則只需要退出代碼。 如果是這種情況,那么您最好編寫:
while(waitpid(pid, &status, WNOHANG) == -1 && errno == EAGAIN) do_whatever_you_want_because_you_decided_not_to_wait();
wait
系統調用沒有辦法告訴您&status
變量還沒errno
通知errno
來填充子進程的退出代碼,在這種情況下,始終將errno
為EAGAIN
。
但是,從我的角度來看,如果與此同時無事可做,那么最好不要使用WNOHANG
。 這樣可以節省CPU周期並節省大量散發到環境中的熱能。
這里
while(waitpid(pid,&status,WNOHANG)==-1) { }
如果不再存在子進程,則waitpid
返回-1
,它始終使while(true)
並導致無限循環。
從waitpid()
的手冊頁開始。
waitpid():
成功時,返回狀態已更改的子進程的ID ; 如果指定了WNOHANG
,並且存在由pid
指定的一個或多個孩子,但尚未更改狀態,則返回0
。 出錯時,返回-1
。
這意味着,當沒有其他孩子等待時,它返回-1
。 所以要么讓它像
if() { /* child process. can be multiple */
}
else { /* parent process */
while(waitpid(pid,&status,WNOHANG) != -1) { /* when there is no more child process exists then it terminate */
}
}
要么
if() { /* child process. can be multiple */
}
else { /* parent process */
while(waitpid(pid,&status,WNOHANG) == -1); /* dummy while ..when there is no more child process exists then it terminate */
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.