vfork()函数和fork()函数实现子进程的异同

来源:互联网 发布:网络宣传有什么好处 编辑:程序博客网 时间:2024/05/22 06:22

      除了fork()函数,还可以用vfork()函数来创建子进程。

      (1)使用fork()创建一个子进程时,子进程只是完全复制父进程的资源。子进程独立于父进程,具有良好的并发性。而vfork()创建的子进程,操作系统并不将父进程的地址空间完全复制到子进程,用vfork()创建的子进程共享父进程的地址空间,也就是说,子进程完全运行在父进程的地址空间上。子进程对该地址空间中任何数据的修改同样为父进程所见。

      (2)使用fork()创建子进程时,哪个进程先运行取决于系统的调度算法。而vfork()保证子进程先运行,当子进程调用exec或exit之后,父进程才可能被调度运行。如果在调用exec或exit之前子进程要依赖父进程的某个行为,就会导致死锁。

      (3)fork()创建子进程时,子进程要将父进程几乎每种资源都复制,所以fork()是一个开销很大的系统调用。假设fork一个子进程后,立即调用exec执行另外一个应用程序,那么fork过程中子进程对父进程地址空间的复制将是一个多余的过程。vfork()不会拷贝父进程的地址空间,这大大减小了系统开销。

#include <stdio.h>#include <sys/types.h>#include <unistd.h>int globVar = 0;int main(void){pid_t  pid;int    var = 0, i;printf("fork is diffirent with vfrok \n");pid = fork();//pid = vfork();switch(pid) {case 0:i = 3;while(i-- > 0){printf("Child process is running\n");globVar++;var++;sleep(1);}printf("Child's globVar = %d,var = %d\n",globVar,var);break;case -1:perror("Process creation failed\n");exit(0);default:i = 5;while(i-- > 0){printf("Parent process is running\n");globVar++;var++;sleep(1);}printf("Parent's globVar = %d ,var = %d\n", globVar ,var);exit(0);}}
      使用fork()创建子进程时,运行结果如下:

      使用fork()创建子进程时,子进程继承了父进程的全局变量和局部变量。子进程中,最后全局变量globVar和局部变量var的值均递增3,分别为3和3,而父进程中两者分别递增5,分别都是5。这证明了子进程有自己独立的地址空间。

  

    注释掉fork()的代码,使用vfork()创建子进程,运行结果如下:




      vfork()创建子进程后,父进程中globVar和var最后均递增了8(但var最后运行结果是2277504,这个还比较费解,暂时还没搞清楚什么原因导致了这个数字出现错乱?).这是因为vfork()的子进程共享父进程的地址空间,子进程修改变量对父进程是可见的。


      fork()创建子进程后,父子进程的执行顺序是不确定的。而vfork(),子进程在父进程之前执行。


注意:使用vfork()时要谨慎,最好不要允许子进程修改与父进程共享的全局变量和局部变量。

原创粉丝点击