在fork还没实现copy on write之前。Unix设计者很关心fork之后立刻执行exec所造成的地址空间浪费,所以引入了vfork系统调用。
vfork有个限制,子进程必须立刻执行_exit或者exec函数。即使fork实现了copy on write,效率也没有vfork高,但是我们不推荐使用vfork,因为几乎每一个vfork的实现,都或多或少存在一定的问题。
结论:
(1)fork子进程拷贝父进程的数据段
Vfork子进程与父进程共享数据段;
(2)fork父、子进程的执行次序不确定
Vfork:子进程先运行,父进程后运行;
Vfork和exec函数族在一起使用。execve替换进程映像(加载程序),替换意味着:代码段、数据段、堆栈段、进程控制块PCB全部替换。
#include <sys/types.h>
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <signal.h>
#include <errno.h>
#include <signal.h>
int main(void )
{
pid_t pid;
int ret = 0;
char *const argv[] = {"ls", "-l", NULL};
printf("befor fork pid:%d \n", getpid());
pid = vfork();
if (pid == -1)
{
perror("tile");
return -1;
}
if (pid > 0)
{
printf("parent: pid:%d \n", getpid());
}
else if (pid == 0)
{
printf("child: %d, parent: %d \n", getpid(), getppid());
//把应用程序启动起来
ret = execve("/bin/ls", argv, NULL);
if (ret == -1)
{
perror("execve:");
}
printf("execve 测试有没有执行\n");
exit(0);
}
printf("fork after....\n");//不会被执行
return 0;
}