1

我想比父进程更早地运行子进程。我只想使用来自子进程的 execv 调用,所以我使用 vfork 而不是 fork。

但是假设 execv 失败并返回,我想从我正在调用 vfork 的函数中返回非零值。

像这样的东西,

int start_test()
{
  int err = 0;
  pid_t pid;
  pid = vfork();
  if(pid == 0) {
   execv(APP, ARGS);
   err = -1;
   _exit(1);
} else if(pid > 0) {
  //Do something else 
}
return err;
}

上面的代码是正确的,还是我应该使用其他机制来比父母更早地运行孩子?

在某些链接上,我读过,我们不应该修改通过 vfork 创建的子进程中的任何父资源(我正在修改 err 变量)。

4

2 回答 2

2

上面的代码是正确的吗?

不,err变量已经在孩子的记忆中,因此父母不会看到它的修改。

我们不应该修改通过 vfork 创建的子进程中的任何父资源(我正在修改 err 变量)。

资源已过时。fork()过去,一些 *nix 系统尝试使用/对来耍花招exec(),但通常这些优化在很大程度上适得其反,导致意想不到的、难以重现的问题。这就是从最新版本的 POSIXvfork()删除的原因。

vfork()通常,您可以在支持它的现代系统上做出以下假设:如果孩子做了操作系统意想不到的事情,孩子将从ed升级vfork()到普通fork()ed 。

例如,在 Linux 上,fork()和之间的唯一区别vfork()是,在后一种情况下,更多的孩子的数据被制成惰性 COW数据。效果是vfork()略快于fork(),但是如果孩子试图访问尚未复制的数据,它可能会承受一些额外的性能损失,因为它们尚未从父节点复制。(注意一个微妙的问题:父进程也可以修改数据。这也会触发 COW 以及父进程和子进程之间的数据复制。)

我只想使用execv来自子进程的调用,所以我使用vfork而不是fork.

vfork()不管vs的处理应该是等价的fork():孩子应该返回一个特殊的退出代码,而父母应该做正常waitpid()的事情并检查退出状态。

否则,如果您想编写可移植的应用程序,请不要使用vfork(): 它不是POSIX 标准的一部分。

PS这篇文章可能也很有趣。如果您仍然想使用vfork(),请阅读这个可怕的官方联机帮助页

于 2015-05-15T07:58:02.450 回答
0

是的。您不应该修改变量err。在父进程中使用waitpid来检查子进程的退出代码。还要检查execv的返回值和errno变量(参见 man execv),以确定execv失败的原因。

于 2015-05-15T07:30:54.300 回答