Chinaunix首页 | 论坛 | 博客
  • 博客访问: 3572001
  • 博文数量: 205
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 7385
  • 用 户 组: 普通用户
  • 注册时间: 2013-01-23 18:56
个人简介

将晦涩难懂的技术讲的通俗易懂

文章分类

全部博文(205)

文章存档

2024年(8)

2023年(9)

2022年(4)

2021年(12)

2020年(8)

2019年(18)

2018年(19)

2017年(9)

2016年(26)

2015年(18)

2014年(54)

2013年(20)

分类: LINUX

2014-11-06 22:55:42

vfork的一个使用误区

——lvyilong316

今天在项目中需要实现让子进程先执行(子进程调用exec),然后再执行父进程,就很自然的想到了vfork。但是发现子进程尚未结束,父进程就执行了。为此做了一下实验:

代码一


点击(此处)折叠或打开

  1. #include <stdio.h>
  2. #include <unistd.h>
  3. int main()
  4. {
  5.    int childpid;
  6.    if( (childpid=vfork()) ==0) //子进程
  7.   {
  8.     printf("child is begin\n");
  9.     sleep(10); //子进程等待10秒钟
  10.     printf("child is end\n");
  11.     exit(0);
  12.   } //父进程
  13.   printf("parent is end\n");
  14.   return 0;
  15. }

运行结果:

可以看到确实是子进程先执行,并且父进程等到子进程结束后(exit)才执行。下面再看一下代码二。

代码二


点击(此处)折叠或打开

  1. #include <stdio.h>
  2. #include <unistd.h>
  3. int main()
  4. {
  5.   int childpid;
  6.   if( (childpid=vfork()) ==0) //子进程
  7.   {
  8.     printf("child is begin\n");
  9.     sleep(10);
  10.     execl("./hello",(char*)0); //hello程序仅仅输出”hello,world”
  11.   } //父进程
  12.   printf("parent is end\n");
  13.   return 0;
  14. }
运行结果:

可以看到子进程虽然先运行了,但是父进程没有等到子进程结束就开始运行了。这是怎么回事呢?再看一看有关vfork的说明就明白了。

vfork最早起源于2.9BSD它与fork的不同就在于它并不将父进程的地址空间完全复制到子进程中,因为子进程会立即调用execvfork出来的子进程是在父进程的空间中运行的,它的存在就是为了exec调用,所以它不需要复制这些东西。如果这时子进程修改了某个变量,这将影响到父进程.

     vforkfork的另一区别是:vfork保证子进程先运行,在它调用execexit后父进程才可能调度运行。如果在调用这两个函数之前子进程依赖于父进程的进一步动作,则会导致死锁。 而fork的父子进程运行顺序是不定的,它取决于内核的调度算法.

问题就在这里,vfork时父进程不是只有在子进程exit后才会执行,当子进程执行exec后父进程也会执行。

那么如何保证“子进程调用exec结束后,父进程再开始执行”呢?很简单,可以用wait。修改代码二如下:

代码三

点击(此处)折叠或打开

  1. #include <stdio.h>
  2. #include <unistd.h>
  3. #include <wait.h>
  4. int main()
  5. {
  6.   int childpid;
  7.   if( (childpid=vfork()) ==0) //子进程
  8.   {
  9.     printf("child is begin\n");
  10.     sleep(10);
  11.     execl("./hello",(char*)0); //hello程序仅仅输出”hello,world”
  12.   } //父进程
  13.   wait(NULL); //等待子进程结束
  14.   printf("parent is end\n");
  15.   return 0;
  16. }

运行结果:

可以看到父进程直到子进程退出才开始执行。
关于vfork的更多细节请参考另一篇博客:http://blog.chinaunix.net/uid-28541347-id-4598097.html

阅读(4093) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~