*******************************************************************************************
>> 调用vfork()创建子进程后,子进程共享父进程的地址空间,并且子进程先运行,当它调用exec或exit之后,父进程才被调度运行,但是如果子进程调用exec函数后,系统就把当前的代码段替换成新的程序代码,所以按道理是父进程没办法继续执行了。
> 这个是Linux下Copy On Write的功劳。子进程调用exec时,内核注意到要写入的区域是跟父进程共享的,并且置有COW标记,就不会直
> 接往里头写,而是给子进程分配新的空间,修改PCB等相关数据结构,然后将执行体加载到新的空间里。
> 其实这个子进程共享父进程的地址空间和Copy On Write是Linux的一个优化手段,如果严格按照POSIX语义(Linux不是原教旨主义
> 者……),vfork之后是要复制整个内存空间而不会共享的。
我不是很理解你想说什么,但从第一句话来看,是错的。
vfork()没有使用COW,它使用的是CLONE_VM,在copy_mm()中这个跳过了复制新的mm_struct。
为什么execve()之后就可以呢?因为它在bprm_mm_init()里又创建了一个新的mm_struct。
man vfork中有提到:
Under Linux, fork(2) is implemented using copy-on-write pages, so the
only penalty incurred by fork(2) is the time and memory required to
duplicate the parent’s page tables, and to create a unique task struc-
ture for the child.
.....
BSD introduced the vfork() system call, which
did not fully copy the address space of the parent process, but bor-
rowed the parent’s memory and thread of control until a call to
execve(2) or an exit occurred.