簡體   English   中英

`waitpid()'總是返回-1

[英]`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來填充子進程的退出代碼,在這種情況下,始終將errnoEAGAIN

    但是,從我的角度來看,如果與此同時無事可做,那么最好不要使用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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM