天天看点

vfork

vfork死循环分析

/***vfork.c***/
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>

int main()
{
   pid_t pid;
   pid = vfork();
   if(pid < ){
      perror("fail to vfork");
      exit();
   }else if(pid == ){
            printf("this is child\n");
            //exit(0);
            return ;
         }
         else printf("this is parent\n");

   return ;

}
           

运行上面这段代码:

vfork

可以看到本该输出2行最终却无限输出!

如果将子进程中的return换成exit最终得到我们想要的输出结果。

————————————————————————————————

为什么 return 会挂掉而 exit 不会?

fork与vfork的区别:

- fork创建的子进程复制父进程的地址空间类容,包括数据段和堆栈段。
- vfork创建的子进程与父进程共享地址空间,包括代码段、数据段和堆栈段。
           

vfork会保证子进程先运行,当子进程调用exec或者exit后父进程才接着往下执行。

在上面的程序中,由于子进程与父进程共享地址空间,当子进程结束时调用return时函数栈返回并被弹出。因此父进程结束时将无法返回,会再次调用main函数从而导致循环!而exit只会返回从而保证了父进程结束时能够正常返回。

以上分析可知vfork创建子进程省去了复制父进程地址空间的开销,大大的提高了运行效率,但是同时又存在潜在的危险。fork虽然不存在这个问题但是效率较低。因此之后fork用到了写时复制进行了优化,提高了安全性的同时也兼顾了效率!