gpt4 book ai didi

c++ - Linux、waitpid、WNOHANG 和僵尸

转载 作者:塔克拉玛干 更新时间:2023-11-02 23:21:59 32 4
gpt4 key购买 nike

我需要能够:

  1. fork 一个进程并使它成为 execvp(我做到了)
  2. 检查子进程execvp是否成功(不知道如何)
  3. 检查子进程是否完成(有问题)

我正在 fork 一个进程,但我没有任何方法来检查 child 的 execvp 是否有效。如果它失败了,我需要能够知道它失败了。目前我正在使用

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

但似乎如果 pid 进程的 execv 失败,waitpid 不会返回 -1。

我该如何检查?我阅读了 waitpid 手册页,但我不清楚;也许我的英语不够好。

编辑:为了解释更多:
我正在为家庭作业构建自己的终端。我需要输入一个命令字符串,比如“ls”,然后我必须执行命令。
子fork之后,子调用execvp来执行命令(在我解析字符串之后),父需要检查命令末尾是否有'&'。
如果命令末尾不存在符号“&”,则父级需要等待子级执行。

所以我需要知道 execvp 是否失败。如果它没有失败,那么 parent 使用 waitpid 等待 child 完成它的执行。如果失败,那么 parent 将不会等待 child 。

最佳答案

#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。

关于c++ - Linux、waitpid、WNOHANG 和僵尸,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13482416/

32 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com