我想在父进程之前运行子进程。我只想从子进程中使用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变量)。
发布于 2015-05-15 15:58:02
上面的代码是正确的吗?
不是的。err变量已经在孩子的内存中,因此父变量看不到它的修改。
我们不应该修改通过vfork创建的子进程中的任何父资源(我正在修改err变量)。
该资源已过时。一些*nix系统过去曾试图使用fork()/exec()对,但通常这些优化在很大程度上适得其反,导致了意想不到的、难以重现的问题。这就是为什么从recent versions of POSIX中移除vfork()的原因。
通常,你可以在支持它的现代系统上对vfork()做出这样的假设:如果孩子做了操作系统意想不到的事情,孩子会从vfork()ed升级到普通的fork()ed。
例如,在Linux上,fork()和vfork()之间的唯一区别是,在后一种情况下,更多的孩子的数据被转换为lazy COW数据。其效果是vfork()比fork()稍微快一些,但是如果它试图访问尚未复制的数据,那么子进程可能会遭受一些额外的性能损失,因为它们还没有从父进程复制。(注意这个微妙的问题: parent也可以修改数据。这还会触发父进程和子进程之间的COW和重复数据。)
我只想使用子进程中的
execv调用,所以我使用vfork而不是fork。
无论是vfork()还是fork(),处理都应该是相同的:父级应该返回一个特殊的退出代码,而父级应该执行正常的waitpid()并检查退出状态。
否则,如果您想编写可移植的应用程序,请不要使用vfork():它不是the POSIX standard的一部分。
P.S. This article可能也会引起人们的兴趣。如果您仍然想使用vfork(),请阅读此scary official manpage。
发布于 2015-05-15 15:30:54
是。您不应该修改变量err。在父进程中使用waitpid检查子进程的退出代码。还要检查execv的返回值和errno变量(参见man execv),以确定execv失败的原因。
https://stackoverflow.com/questions/30252017
复制相似问题