在没有 fork() 的情况下创建子进程
Creating a child process WITHOUT fork()
有没有办法在没有 fork()
的情况下仅使用 execvp()
来启动子进程?
与 Windows 系统不同,在这些系统中,创建新进程和执行新进程映像是一步完成的,Linux 和其他类 UNIX 系统将它们作为两个不同的步骤进行。
fork
函数精确复制调用进程,实际上 returns 两次,一次到父进程,一次到子进程。 execvp
函数(以及 exec
系列中的其他函数)在同一进程中执行新的过程映像,覆盖现有的过程映像。
您可以在不先调用 fork
的情况下调用 execvp
。如果是这样,那只意味着当前的 运行 程序消失并被给定的程序替换。但是,fork
是创建新进程的方式。
你的问题的迂腐答案是否定的。创建新进程的只有系统调用是fork
。 execvp
(称为execve
)的系统调用将新的程序加载到现有进程中,这是另一回事。
除了 fork
(例如 vfork
、rfork
、clone
)之外,某些 Unix 种类还有创建新进程的额外系统调用,但它们很小fork
本身的变体,其中 none 是 POSIX 标准的一部分,该标准指定了您可以依靠 anything 调用自身的功能一个 Unix。
稍微有用的答案是您可能正在寻找 posix_spawn
,它是一个将 fork
和 exec
包装到一个操作中的库例程,但我发现它 比我自己写 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
本身只会调用 fork
或 vfork
。但是,GNU/linux 中不再是这种情况。 posix_spawn
本身可能比 fork
更有效,此外,当代码尝试 运行 不同的可执行文件时,它在概念上可能更适合。
如果您不担心可移植性,您可以放弃 posix 并直接将自己耦合到您的目标内核。在 linux 上,创建子进程的系统调用是 clone。在回答这个问题时,手册页提供了三种变体的文档,包括相对较新的 clone3
.
我相信您可以从手册页中获取示例并添加对 childFunc
的 execvp
调用。不过我还没试过!
有没有办法在没有 fork()
的情况下仅使用 execvp()
来启动子进程?
与 Windows 系统不同,在这些系统中,创建新进程和执行新进程映像是一步完成的,Linux 和其他类 UNIX 系统将它们作为两个不同的步骤进行。
fork
函数精确复制调用进程,实际上 returns 两次,一次到父进程,一次到子进程。 execvp
函数(以及 exec
系列中的其他函数)在同一进程中执行新的过程映像,覆盖现有的过程映像。
您可以在不先调用 fork
的情况下调用 execvp
。如果是这样,那只意味着当前的 运行 程序消失并被给定的程序替换。但是,fork
是创建新进程的方式。
你的问题的迂腐答案是否定的。创建新进程的只有系统调用是fork
。 execvp
(称为execve
)的系统调用将新的程序加载到现有进程中,这是另一回事。
除了 fork
(例如 vfork
、rfork
、clone
)之外,某些 Unix 种类还有创建新进程的额外系统调用,但它们很小fork
本身的变体,其中 none 是 POSIX 标准的一部分,该标准指定了您可以依靠 anything 调用自身的功能一个 Unix。
稍微有用的答案是您可能正在寻找 posix_spawn
,它是一个将 fork
和 exec
包装到一个操作中的库例程,但我发现它 比我自己写 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
本身只会调用 fork
或 vfork
。但是,GNU/linux 中不再是这种情况。 posix_spawn
本身可能比 fork
更有效,此外,当代码尝试 运行 不同的可执行文件时,它在概念上可能更适合。
如果您不担心可移植性,您可以放弃 posix 并直接将自己耦合到您的目标内核。在 linux 上,创建子进程的系统调用是 clone。在回答这个问题时,手册页提供了三种变体的文档,包括相对较新的 clone3
.
我相信您可以从手册页中获取示例并添加对 childFunc
的 execvp
调用。不过我还没试过!