fork():创建子进程的函数,是大家比较熟悉的吧。pid_t id = fork();
这里的vfork();也是创建子进程的函数。现在我们来剖析一下它们吧。
第一例:
先看一个fork()的例子哦。
对于fork()而言,创建子进程成功后直接打印出父子进程执行的两条语句。即:
这里要特别强调的是:父子进程的调度的顺序是由调度器决定的。
再看看vfork()函数:
这里有一个重要的函数:exit(1);这也是vfork()中特别重要的一点,如果在子进程中不使用exit(1)会怎么样呢?这意味着父进程永远不会运行。如:
这里的父进程的pid在创建子进程前是多少现在还是多少。即子进程一直在运行。这就是因为没有使用exit(1)的原因。
子进程如果调用了exit(1);说明子进程结束后调用父进程。(这里也说明vfork()的一大特点:先调用子进程,等子进程的exit(1)被调用后,再调用父进程)所以结果如下:
第二例:
看一看它们的地址空间哦:
vfork():
这里看一下他们的地址空间是如何分配的。看看运行的结果:
看的出来,他们的虚拟地址空间是一样的,这一点和fork()函数是一样的。重要的是,当子进程中将g_val的值改变了之后,父进程也随之改变,这一点却是和fork()不一样的,进而引出vfork()函数的另一大特点:在子进程调用exit之前,它在父进程的空间中运行,也就是说会更改父进程的数据段、栈和堆。。
如:
运行结果:
fork()函数:它的虚拟地址是相同的,但是值却不相同,它们所指的物理地址也是不同的。
据上所述,总结一下fork()与vfork()的区别吧~~~:>>
主要为两点:
(1)执行次序:fork():对父子进程的调度室由调度器决定的;
vfork():是先调用子进程,等子进程的exit(1)被调用后,再调用父进程;
(2)对数据段的影响:fork():父子进程不共享一段地址空间,修改子进程,父进程的内容并不会受影响。
vfork():在子进程调用exit之前,它在父进程的空间中运行,也就是说会更改父进程的数据段、 栈和堆。。即共享代码区和数据区,且地址和内容都是一样的。
第三例:
这个例子是关于vfork()创建子进程,且子进程用return返回。
运行结果:
子进程返回时,运行结果是执行后程序一直不断地重复运行,不断创建子进程;
子进程return 1在一个函数中是正常的返回过程,它会使得程序返回到函数被调用处,回复之前的执行流程,又会输出父子进程,所以不像exit一样,直接终止进程。
就先说到这里啦,有什么建议还会做改进哦~~