就内存分配效率而言,fork()
在子代码中的 a 之后,如果我使用它执行一个程序execve()
将比不使用它执行的同一程序更有效,execve()
因为子代码不会分配堆栈和堆是正确的父亲却只有自己?
朴素的例子:
没有执行
[..some father code...]
int i;
if(!fork()) {
sum() //from an #include "porg.h"
}
与执行
[..some father code...]
if(!fork()) {
execve("sum", NULL, NULL); //sum is a program which executes i=2+3
}
第二个在内存分配方面更好?是更好地替换我的进程的整个虚拟地址空间,还是更好地通过调用另一个程序中的函数来运行上述代码,该程序包含在#include“prog”中,就完成的操作数量而言如此以及在程序执行期间所携带的内存方面?
第
if
一个片段中的代码包含一个添加和一个分配。这就像任何事情一样简单,它会编译成机器代码中的大约两条指令。在第二个中,有一堆参数被加载并推送到堆栈,一个函数调用,libc 的一些内部处理,这包括将参数移动到系统调用的正确位置,然后是系统调用本身。
系统调用需要切换到内核模式(需要多少成本,取决于系统),在内核中查找以找到实际处理的系统调用,然后执行程序
sum
。执行程序需要找到包含该程序的文件,将其加载到内存中(可能等待磁盘),解释 ELF 标头以了解将程序的每个部分放在内存中的位置,设置一些内存映射,可能是页表所以...我想你明白了。
假设是不对的。
sum
叉子和叉子都没有明确使用堆。但是在 中sum
,C 运行时可能会在程序启动时初始化一些堆结构。堆栈也有类似的可能性。然而,这是一个值得思考的合理问题。如果父进程在子进程运行时也在修改内存,则子进程将托管所有已修改内存的副本(写时复制)。通常孩子正在执行一个子任务并且只使用该数据的一个子集。
对于更大的父进程和运行时间更长的子进程,它可能很重要。