我正在尝试在 C 中运行应用程序,但我能找到的唯一方法是相当容易使用,如下所示:
system("command here");
当然,它有效,但它真的很慢(尤其是在重复很多时)。我只是想知道是否有一种无需与 shell 交互就可以运行程序的方法,例如python 的 subprocess 模块。
我听说过execl
,我会使用它(fork
当然,首先使用它),但我想知道是否有一种更简单的方法不需要先分叉。
编辑:我也希望能够知道程序的返回码
我相信您已经知道,system
已经采用了该fork/exec
策略。我了解您想要绕过 shell 并正在寻找一种简单的方法,我只是说您可以像fork/exec
在system
. 事实上,这样做可能是最直接的。Gabe 在评论中提到的另一种选择是posix_spawn
.
一个更快(但显然不鼓励)的替代方法是vfork()
/ exec
,但这通常不鼓励并且在最新的 POSIX 标准中已过时。
4.3BSD;POSIX.1-2001(但标记为 OBSOLETE)。POSIX.1-2008 删除了 vfork() 的规范。
它意味着紧跟在exec
or之后_exit
。否则,由于虚拟内存页面和页表没有重复(子使用相同的数据/堆/堆栈段),可能会出现各种奇怪的错误。父/调用进程阻塞,直到子exec
s 或_exit
s。Regularfork
的现代实现具有接近 的速度的写时复制语义,而没有由的内存共享语义vfork
引起的潜在错误。vfork
如果您想进一步控制内存共享语义和进程继承,以及随之而来的潜在加速(并且在 Linux 上),请查看clone()
(wrapper for system-call sys_clone()
),这是一些创建进程的系统调用委托他们的工作到。请务必仔细梳理所有各种标志。
可以waitpid
用来获取进程的退出状态。
如果既不system()
也不popen()
提供您需要的机制,那么简单的方法是使用fork()
and execv()
(或者,也许,,execl()
但参数列表必须在编译时固定,而不是变量,才能使用它)。真的!做fork()
和并不难exec()
,任何替代方法都将封装该处理。
The Python subprocess module is simply hiding fork()
and exec()
for you behind a convenient interface. That's probably appropriate for a high-level language like Python. C is a lower-level language and doesn't really need the complexity.
The hard way to do it is with posix_spawn()
. You have to create arguments to describe all the actions you want done in the child between the fork()
and the exec()
, which is far harder to set up than it is to simply do the fork()
, make the changes, and then use exec()
after all. This (posix_spawn()
) is what you get when you design the code to spawn a child process without visibly using fork()
and exec()
and ensure that it can handle almost any reasonable circumstance.
You'll need to consider whether you need to use wait()
or waitpid()
or a variant to determine when the child is complete. You may need to consider whether to handle the SIGCHLD signal (which will notify you when a child dies).