簡體   English   中英

Linux,waitpid,WNOHANG和僵屍

[英]Linux, waitpid, WNOHANG and zombies

我需要能夠:

  1. fork一個進程並使其成為execvp(我做到了)
  2. 檢查子進程execvp是否成功(不知道如何)
  3. 檢查子進程是否完成(有問題)

我正在尋求一個過程,我沒有辦法檢查孩子的execvp是否有效。 如果失敗了,我需要知道它失敗了。 目前我正在使用

-1 != waitpid( pid, &status, WNOHANG )

但似乎如果pid進程的execv失敗,waitpid不會返回-1。

我該怎么檢查? 我讀了waitpid手冊頁,但我不清楚; 也許我的英語不夠好。

編輯:為了解釋更多:
我正在為家庭作業建立自己的終端。 我需要輸入一個命令字符串,讓我們說“ls”,然后我必須執行命令。
在子forks之后,子進程調用execvp來執行命令(在我解析字符串之后),並且父進程需要檢查命令末尾是否有'&'。
如果命令末尾不存在符號'&',則父進程需要等待子進程執行。

所以我需要知道execvp是否失敗了。 如果它沒有失敗,則父使用waitpid等待子進程完成執行。 如果失敗,那么父母將不會等待孩子。

#2的常見解決方案是在fork()之前打開一個管道,然后在exec之后的子代中寫入它。 在父母中,成功閱讀意味着執行失敗; 不成功的讀取意味着exec成功並且寫入從未發生過。

// ignoring all errors except from execvp...
int execpipe[2];
pipe(execpipe);
fcntl(execpipe[1], F_SETFD, fcntl(execpipe[1], F_GETFD) | FD_CLOEXEC);
if(fork() == 0)
{
    close(execpipe[0]);
    execvp(...); // on success, never returns
    write(execpipe[1], &errno, sizeof(errno));
    // doesn't matter what you exit with
    _exit(0);
}
else
{
    close(execpipe[1]);
    int childErrno;
    if(read(execpipe[0], &childErrno, sizeof(childErrno)) == sizeof(childErrno))
    {
        // exec failed, now we have the child's errno value
        // e.g. ENOENT
    }
}

這使得父母可以明確地知道exec是否成功,並且作為副產品,如果不成功則是errno值。

如果exec成功,子進程可能仍然失敗並帶有退出代碼,並且使用WEXITSTATUS宏檢查狀態也會給出該條件。

注意:使用WNOHANG標志調用waitpid是非阻塞的,您可能需要輪詢該進程,直到返回有效的pid。

如果成功,exec調用根本不應該返回,因為它用另一個替換當前進程映像,所以如果這樣做則意味着發生了錯誤:

execvp(...);
/* exec failed and you should exit the
   child process here with an error */
exit(errno);

要讓父進程知道exec失敗,您應該閱讀子進程的狀態:

waitpid(pid, &status, WNOHANG);

然后使用手冊頁中的WEXITSTATUS(status)宏:

WEXITSTATUS(status)返回子項的退出狀態。 這包含在調用exit(3)或_exit(2)時指定的子參數的最低有效8位或作為main()中的return語句的參數

注意最后一個語句意味着如果exec成功並運行該命令,您將獲得該命令的main()函數的退出狀態,換句話說, 您無法通過這種方式可靠地區分失敗的exec和失敗的命令之間的區別 ,所以這取決於你是否重要。

另一個問題:

如果命令末尾不存在符號'&',則父進程需要等待子進程執行。

你需要在你的程序中的某個時刻調用子進程上的wait() ,而不管是什么&以避免讓子進程處於僵屍狀態,

注意:當你使用WNOHANG這意味着如果沒有進程改變了狀態, waitpid()將立即返回,即它不會阻塞,我假設你知道,否則使用wait()或調用waitpid()作為你的一部分主循環。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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