在嵌入式平台上(没有交换分区),我有一个应用程序,其主进程占用了大部分可用的物理内存。问题是我想从我的应用程序中启动一个外部shell脚本,但是使用fork()要求在子进程(最终会将其自身更小)之前有足够的内存用于我的原始进程2x
那么有没有办法从C程序调用shell脚本而不会产生fork()的内存开销?
我考虑过一些变通办法,例如有一个辅助较小的进程负责创建shell,或者有一个“观察者”脚本,我通过触摸文件或某些信号发出信号,但我更喜欢更简单的事情。 / p>
答案 0 :(得分:8)
某些UNIX实现将为您提供vfork
(Single UNIX规范的一部分),它与fork
完全相同,只是它与父级共享所有内容。
使用vfork
,在调用exec
以使用其他进程覆盖地址空间之前,您可以在子进程中执行的内容非常有限 - 这基本上就是构建vfork
的内容for,fork
序列的fork/exec
的最小副本版本。
答案 1 :(得分:6)
如果你的系统有一个MMU,那么通常fork()
是使用copy-on-write实现的,它在调用fork()
时实际上并没有分配更多的内存。只有在写到与父进程共享的任何页面时,才会分配额外的内存。然后exec()
将丢弃这些页面。
如果您知道自己没有MMU,那么fork()
确实可能是使用实际副本实现的。另一种方法可能是有一个辅助进程负责产生子shell,你可以使用管道进行通信。
答案 2 :(得分:0)
答案 3 :(得分:-1)
听起来好像在这种情况下谨慎行动是将shell脚本(如果可能)移植到C,并在过程中执行它;所以你根本不需要分叉。
然后再说;我不知道你实际上想要做什么。
答案 4 :(得分:-3)
不是让你的进程产生一个shell,而是在你的进程中启动一个shell(在前台),然后在shell中将它分叉。
system("/bin/ash /scripts/bgtask");
/ scripts / bgtask是:
/bin/ash /scripts/propertask &
这样,您只能将shell使用的内存加倍,而不是主程序加倍。你的主程序忙于产生两个shell的时间:原始启动bgtask和它启动的后台克隆,然后第一个shell分配的内存再次空闲。