在没有 fork() 的情况下创建子进程

Creating a child process WITHOUT fork()

有没有办法在没有 fork() 的情况下仅使用 execvp() 来启动子进程?

与 Windows 系统不同,在这些系统中,创建新进程和执行新进程映像是一步完成的,Linux 和其他类 UNIX 系统将它们作为两个不同的步骤进行。

fork 函数精确复制调用进程,实际上 returns 两次,一次到父进程,一次到子进程。 execvp 函数(以及 exec 系列中的其他函数)在同一进程中执行新的过程映像,覆盖现有的过程映像。

您可以在不先调用 fork 的情况下调用 execvp。如果是这样,那只意味着当前的 运行 程序消失并被给定的程序替换。但是,fork创建新进程的方式

你的问题的迂腐答案是否定的。创建新进程的只有系统调用是forkexecvp(称为execve)的系统调用将新的程序加载到现有进程中,这是另一回事。

除了 fork(例如 vforkrforkclone)之外,某些 Unix 种类还有创建新进程的额外系统调用,但它们很小fork 本身的变体,其中 none 是 POSIX 标准的一部分,该标准指定了您可以依靠 anything 调用自身的功能一个 Unix。

稍微有用的答案是您可能正在寻找 posix_spawn,它是一个将 forkexec 包装到一个操作中的库例程,但我发现它 比我自己写 fork+exec 子程序更麻烦 正确使用它。 YMMV.

正如用户 zwol 已经解释的那样,execve() 不会分叉新进程。相反,它取代了当前进程的地址space和CPU状态, 从可执行文件名加载新地址 space 并从 main() 带有参数列表 argv 和环境变量列表 envp。 它保留 pid 和打开的文件。

int execve(const char *filename,char *const argv [],char *const envp[]);

filename: 运行
的可执行文件名 argv:命令行参数
envp:环境变量设置(如$PATH$HOME等)

posix_spawn 是唯一一种无需直接调用 fork 即可创建子进程的 posix 兼容方式。我说 'directly' 是因为历史上 posix_spawn 本身只会调用 forkvfork。但是,GNU/linux 中不再是这种情况。 posix_spawn 本身可能比 fork 更有效,此外,当代码尝试 运行 不同的可执行文件时,它在概念上可能更适合。

如果您不担心可移植性,您可以放弃 posix 并直接将自己耦合到您的目标内核。在 linux 上,创建子进程的系统调用是 clone。在回答这个问题时,手册页提供了三种变体的文档,包括相对较新的 clone3.

我相信您可以从手册页中获取示例并添加对 childFuncexecvp 调用。不过我还没试过!