源地址:http://blog.csdn.net/jianchi88/article/details/6985326 有大量驱动文章

fork()与vfock()都是创建一个进程,那他们有什么区别呢?总结有以下三点区别:
1.  fork  ():子进程拷贝父进程的数据段,代码段
    vfork ( ):子进程与父进程共享数据段
2.  fork ()父子进程的执行次序不确定
    vfork 保证子进程先运行,在调用exec 或exit 之前与父进程数据是共享的,在它调用exec
     或exit 之后父进程才可能被调度运行。
3.  vfork ()保证子进程先运行,在她调用exec 或exit 之后父进程才可能被调度运行。如果在
   调用这两个函数之前子进程依赖于父进程的进一步动作,则会导致死锁。
下面通过几个例子加以说明:
第一:子进程拷贝父进程的代码段的例子:

  1. #include<sys/types.h>
  2. #include<unistd.h>
  3. #include<stdio.h>
  4. int main()
  5. {
  6. pid_t pid;
  7. pid = fork();
  8. if(pid<0)
  9. printf("error in fork!\n");
  10. else if(pid == 0)
  11. printf("I am the child process,ID is %d\n",getpid());
  12. else
  13. printf("I am the parent process,ID is %d\n",getpid());
  14. return 0;
  15. }
#include<sys/types.h>
#include<unistd.h>
#include<stdio.h> int main()
{
pid_t pid;
pid = fork();
if(pid<0)
printf("error in fork!\n");
else if(pid == 0)
printf("I am the child process,ID is %d\n",getpid());
else
printf("I am the parent process,ID is %d\n",getpid());
return 0; }

运行结果:

  1. [root@localhost fork]# gcc -o fork fork.c
  2. [root@localhost fork]# ./fork
[root@localhost fork]# gcc -o fork fork.c
[root@localhost fork]# ./fork
  1. I am the child process,ID is 4711
  2. I am the parent process,ID is 4710
I am the child process,ID is 4711
I am the parent process,ID is 4710

为什么两条语 都会打印呢?这是因为fork()函数用于从已存在的进程中创建一个新的进
程,新的进程称为子进程,而原进程称为父进程,fork ()的返回值有两个,子进程返回0,
父进程返回子进程的进程号,进程号都是非零的正整数,所以父进程返回的值一定大于零,
在pid=fork();语句之前只有父进程在运行,而在pid=fork();之后,父进程和新创建的子进程
都在运行,所以如果pid==0,那么肯定是子进程,若pid !=0 (事实上肯定大于0),那么是
父进程在运行。而我们知道fork()函数子进程是拷贝父进程的代码段的,所以子进程中同样

if(pid<0)
         printf("error in fork!");
     else if(pid==0)
         printf("I am the child process,ID is %d\n",getpid());
     else
         printf("I am the parent process,ID is %d\n",getpid());
}
这么一段代码,所以上面这段代码会被父进程和子进程各执行一次,最终由于子进程的pid= =0,

而打印出第一句话,父进程的pid>0,而打印出第二句话。于是得到了上面的运行结果。
再来看一个拷贝数据段的例子:

  1. #include<sys/types.h>
  2. #include<unistd.h>
  3. #include<stdio.h>
  4. int main()
  5. {
  6. pid_t pid;
  7. int cnt = 0;
  8. pid = fork();
  9. if(pid<0)
  10. printf("error in fork!\n");
  11. else if(pid == 0)
  12. {
  13. cnt++;
  14. printf("cnt=%d\n",cnt);
  15. printf("I am the child process,ID is %d\n",getpid());
  16. }
  17. else
  18. {
  19. cnt++;
  20. printf("cnt=%d\n",cnt);
  21. printf("I am the parent process,ID is %d\n",getpid());
  22. }
  23. return 0;
  24. }
#include<sys/types.h>
#include<unistd.h>
#include<stdio.h> int main()
{
pid_t pid;
int cnt = 0;
pid = fork();
if(pid<0)
printf("error in fork!\n");
else if(pid == 0)
{
cnt++;
printf("cnt=%d\n",cnt);
printf("I am the child process,ID is %d\n",getpid());
}
else
{
cnt++;
printf("cnt=%d\n",cnt);
printf("I am the parent process,ID is %d\n",getpid());
}
return 0;
}

大家觉着打印出的值应该是多少呢?是不是2 呢?先来看下运行结果吧

  1. [root@localhost fork]# ./fork2
  2. cnt=1
  3. I am the child process,ID is 5077
  4. cnt=1
  5. I am the parent process,ID is 5076
[root@localhost fork]# ./fork2
cnt=1
I am the child process,ID is 5077
cnt=1
I am the parent process,ID is 5076

为什么不是2 呢?因为我们一次强调fork ()函数子进程拷贝父进程的数据段代码段,所以
cnt++;
    printf("cnt= %d\n",cnt);

return 0
将被父子进程各执行一次,但是子进程执行时使自己的数据段里面的(这个数据段是从父进
程那copy 过来的一模一样)count+1,同样父进程执行时使自己的数据段里面的count+1,
他们互不影响,与是便出现了如上的结果。

那么再来看看vfork ()吧。如果将上面程序中的fork ()改成vfork(),运行结果是什么
样子的呢?

  1. [root@localhost fork]# gcc -o fork3 fork3.c
  2. [root@localhost fork]# ./fork3
  3. cnt=1
  4. I am the child process,ID is 4711
  5. cnt=1
  6. I am the parent process,ID is 4710
  7. 段错误
[root@localhost fork]# gcc -o fork3 fork3.c
[root@localhost fork]# ./fork3
cnt=1
I am the child process,ID is 4711
cnt=1
I am the parent process,ID is 4710
段错误

本来vfock()是共享数据段的,结果应该是2,为什么不是预想的2 呢?先看一个知识点:
vfork 和fork 之间的另一个区别是:vfork 保证子进程先运行,在她调用exec 或exit 之
后父进程才可能被调度运行。如果在调用这两个函数之前子进程依赖于父进程的进一步动
作,则会导致死锁。
这样上面程序中的fork ()改成vfork()后,vfork ()创建子进程并没有调用exec 或exit,
所以最终将导致死锁。
怎么改呢?看下面程序:

  1. #include<sys/types.h>
  2. #include<unistd.h>
  3. #include<stdio.h>
  4. int main()
  5. {
  6. pid_t pid;
  7. int cnt = 0;
  8. pid = vfork();
  9. if(pid<0)
  10. printf("error in fork!\n");
  11. else if(pid == 0)
  12. {
  13. cnt++;
  14. printf("cnt=%d\n",cnt);
  15. printf("I am the child process,ID is %d\n",getpid());
  16. _exit(0);
  17. }
  18. else
  19. {
  20. cnt++;
  21. printf("cnt=%d\n",cnt);
  22. printf("I am the parent process,ID is %d\n",getpid());
  23. }
  24. return 0;
  25. }
#include<sys/types.h>
#include<unistd.h>
#include<stdio.h> int main()
{
pid_t pid;
int cnt = 0;
pid = vfork();
if(pid<0)
printf("error in fork!\n");
else if(pid == 0)
{
cnt++;
printf("cnt=%d\n",cnt);
printf("I am the child process,ID is %d\n",getpid());
_exit(0);
}
else
{
cnt++;
printf("cnt=%d\n",cnt);
printf("I am the parent process,ID is %d\n",getpid());
}
return 0; }

如果没有_exit(0)的话,子进程没有调用exec 或exit,所以父进程是不可能执行的,在子
进程调用exec 或exit 之后父进程才可能被调度运行。
所以我们加上_exit(0);使得子进程退出,父进程执行,这样else 后的语句就会被父进程执行,
又因在子进程调用exec 或exit之前与父进程数据是共享的,所以子进程退出后把父进程的数
据段count改成1 了,子进程退出后,父进程又执行,最终就将count变成了2,看下实际
运行结果:

  1. [root@localhost fork]# gcc -o fork3 fork3.c
  2. [root@localhost fork]# ./fork3
  3. cnt=1
  4. I am the child process,ID is 4711
  5. cnt=2
  6. I am the parent process,ID is 4710
[root@localhost fork]# gcc -o fork3 fork3.c
[root@localhost fork]# ./fork3
cnt=1
I am the child process,ID is 4711
cnt=2
I am the parent process,ID is 4710

网上抄的一段,可以再理解理解:
为什么会有vfork,因为以前的fork 很傻, 它创建一个子进程时,将会创建一个新的地址
空间,并且拷贝父进程的资源,而往往在子进程中会执行exec 调用,这样,前面的拷贝工
作就是白费力气了,这种情况下,聪明的人就想出了vfork,它产生的子进程刚开始暂时与
父进程共享地址空间(其实就是线程的概念了),因为这时候子进程在父进程的地址空间中
运行,所以子进程不能进行写操作,并且在儿子 霸占”着老子的房子时候,要委屈老子一
下了,让他在外面歇着(阻塞),一旦儿子执行了exec 或者exit 后,相 于儿子买了自己的
房子了,这时候就相 于分家了。

转:fork与vfork的区别的更多相关文章

  1. fork()和vfork()的区别(转载)

    fork和vfork 转载 http://coolshell.cn/articles/12103.html 在知乎上,有个人问了这样的一个问题--为什么vfork的子进程里用return,整个程序会挂 ...

  2. fork()和vfork()的区别,signal函数用法,exec()系列函数的用法小结

    一:fork()和vfork()的区别:    fork()函数可以创建子进程,有两个返回值,即调用一次返回两个值,一个是父进程调用fork()后的返回值,该返回值是刚刚创建的子进程的ID;另一个是子 ...

  3. fork和vfork的区别

    参见百度百科API说明: fork 头文件: #include<unistd.h> #include<sys/types.h> 函数原型: pid_t fork( void); ...

  4. fork与vfork的区别与联系

    fork()与vfock()都是创建一个进程,那他们有什么区别呢?总结有以下三点区别: 1. fork ():子进程拷贝父进程的数据段,代码段 vfork ( ):子进程与父进程共享数据段 2. fo ...

  5. 嵌入式 fork与vfork的区别

    fork()与vfock()都是创建一个进程,那他们有什么区别呢?总结有以下三点区别: 1.  fork  ():子进程拷贝父进程的数据段,代码段     vfork ( ):子进程与父进程共享数据段 ...

  6. fork与vfork的区别

    fork()与vfock()都是创建一个进程,那他们有什么区别呢?总结有以下三点区别: 1.  fork  ():子进程拷贝父进程的数据段,代码段     vfork ( ):子进程与父进程共享数据段 ...

  7. fork 和 vfork 的区别与联系

    vfork用于创建一个新进程,而该新进程的目的是exec一个新进程,vfork和fork一样都创建一个子进程,但是它并不将父进程的地址空间完全复制到子进程中,不会复制页表.因为子进程会立即调用exec ...

  8. fork与vfork

    先看一个fork的例子: ; int main(void) { int var, pid; ; ) { printf("vfork error"); exit(-); } ) { ...

  9. Linux下fork()、vfork()、clone()和exec()的区别

    转自Linux下fork().vfork().clone()和exec()的区别 前三个和最后一个是两个类型.前三个主要是Linux用来创建新的进程(线程)而设计的,exec()系列函数则是用来用指定 ...

随机推荐

  1. (转)Android--使用Canvas绘图

    转:http://www.cnblogs.com/plokmju/p/android_canvas.html 前言 除了使用已有的图片之外,Android应用常常需要在运行时根据场景动态生成2D图片, ...

  2. VS2010-MFC(图形图像:GDI对象之画刷CBrush)

    转自:http://www.jizhuomi.com/software/248.html 上一节讲的是画笔CPen的用法,前面也说了,GDI对象中最常用的就是画笔和画刷,本节就讲讲画刷CBrush. ...

  3. 盒子阴影 box-shadow

    <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title> ...

  4. 【Vue】组件的基础与组件间通信

    转载:https://segmentfault.com/a/1190000016409329 Vue.js 最核心的功能就是组件(Component),从组件的构建.注册到组件间通信,Vue .x 提 ...

  5. 2019牛客国庆集训派对day5

    2019牛客国庆集训派对day5 I.Strange Prime 题意 \(P=1e10+19\),求\(\sum x[i] mod P = 0\)的方案数,其中\(0 \leq x[i] < ...

  6. WPF 字体描边的实现方式

    原文:WPF 字体描边的实现方式   <local:TextPath x:Name="PathEdge" Fill="Red" Stroke=" ...

  7. 【颓废篇】easyx--2048

    整天待在机房是不是,一直保持学术的态度就比较的难啊~ 所以本蒟蒻就在学术之余学了些奇技淫巧,然后就写了一些奇奇怪怪的程序啊,比如让我们小组dalao们都颓得不亦乐乎的2048~~ 当然,2048的实现 ...

  8. 一个页面上调用多个setInterval失效解决办法(使用于同一时间间隔)

    将方法封装在一起,只调用一个setInterval window.setInterval( function () { $.ajax({ type: "GET", url: '/M ...

  9. 算法系列:Shell 排序

    Copyright © 1900-2016, NORYES, All Rights Reserved. http://www.cnblogs.com/noryes/ 欢迎转载,请保留此版权声明. -- ...

  10. 在python2中的编码

    在python2中的编码 #_author:star#date:2019/10/29'''字符编码:ASCII:只能存英文和拉丁字符,gb2312:只能6700中文,1980年gbk1.0:存了200 ...