转:fork与vfork的区别
源地址:http://blog.csdn.net/jianchi88/article/details/6985326 有大量驱动文章
fork()与vfock()都是创建一个进程,那他们有什么区别呢?总结有以下三点区别: 
1.  fork  ():子进程拷贝父进程的数据段,代码段 
    vfork ( ):子进程与父进程共享数据段 
2.  fork ()父子进程的执行次序不确定 
    vfork 保证子进程先运行,在调用exec 或exit 之前与父进程数据是共享的,在它调用exec
     或exit 之后父进程才可能被调度运行。 
3.  vfork ()保证子进程先运行,在她调用exec 或exit 之后父进程才可能被调度运行。如果在
   调用这两个函数之前子进程依赖于父进程的进一步动作,则会导致死锁。 
下面通过几个例子加以说明: 
第一:子进程拷贝父进程的代码段的例子:
- #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;
 - }
 
#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; }
运行结果:
- [root@localhost fork]# gcc -o fork fork.c
 - [root@localhost fork]# ./fork
 
[root@localhost fork]# gcc -o fork fork.c
[root@localhost fork]# ./fork
- I am the child process,ID is 4711
 - 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,而打印出第二句话。于是得到了上面的运行结果。 
再来看一个拷贝数据段的例子:
- #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;
 - }
 
#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 呢?先来看下运行结果吧
- [root@localhost fork]# ./fork2
 - cnt=1
 - I am the child process,ID is 5077
 - cnt=1
 - 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(),运行结果是什么 
样子的呢?
- [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
 - 段错误
 
[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,
所以最终将导致死锁。 
怎么改呢?看下面程序:
- #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;
 - }
 
#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,看下实际 
运行结果:
- [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
 
[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的区别的更多相关文章
- fork()和vfork()的区别(转载)
		
fork和vfork 转载 http://coolshell.cn/articles/12103.html 在知乎上,有个人问了这样的一个问题--为什么vfork的子进程里用return,整个程序会挂 ...
 - fork()和vfork()的区别,signal函数用法,exec()系列函数的用法小结
		
一:fork()和vfork()的区别: fork()函数可以创建子进程,有两个返回值,即调用一次返回两个值,一个是父进程调用fork()后的返回值,该返回值是刚刚创建的子进程的ID;另一个是子 ...
 - fork和vfork的区别
		
参见百度百科API说明: fork 头文件: #include<unistd.h> #include<sys/types.h> 函数原型: pid_t fork( void); ...
 - fork与vfork的区别与联系
		
fork()与vfock()都是创建一个进程,那他们有什么区别呢?总结有以下三点区别: 1. fork ():子进程拷贝父进程的数据段,代码段 vfork ( ):子进程与父进程共享数据段 2. fo ...
 - 嵌入式 fork与vfork的区别
		
fork()与vfock()都是创建一个进程,那他们有什么区别呢?总结有以下三点区别: 1. fork ():子进程拷贝父进程的数据段,代码段 vfork ( ):子进程与父进程共享数据段 ...
 - fork与vfork的区别
		
fork()与vfock()都是创建一个进程,那他们有什么区别呢?总结有以下三点区别: 1. fork ():子进程拷贝父进程的数据段,代码段 vfork ( ):子进程与父进程共享数据段 ...
 - fork 和 vfork 的区别与联系
		
vfork用于创建一个新进程,而该新进程的目的是exec一个新进程,vfork和fork一样都创建一个子进程,但是它并不将父进程的地址空间完全复制到子进程中,不会复制页表.因为子进程会立即调用exec ...
 - fork与vfork
		
先看一个fork的例子: ; int main(void) { int var, pid; ; ) { printf("vfork error"); exit(-); } ) { ...
 - Linux下fork()、vfork()、clone()和exec()的区别
		
转自Linux下fork().vfork().clone()和exec()的区别 前三个和最后一个是两个类型.前三个主要是Linux用来创建新的进程(线程)而设计的,exec()系列函数则是用来用指定 ...
 
随机推荐
- JavaScript开发人员必知的10个关键习惯
			
还在一味没有目的的编写JavaScript代码吗?那么你就OUT了!让我们一起来看看小编为大家搜罗的JavaScript开发人员应该具备的十大关键习惯吧! 随着新技术的不断发展,JavaScript已 ...
 - Go前言
			
Go语言为并发而生 硬件制造商正在为处理器添加越来越多的内核以来提高性能.所有数据中心都在这些处理器上运行,今天的应用程序使用多个微服务来维护数据库连接,消息队列和维护缓存.所以,开发的软件和编程语言 ...
 - java_过滤器
			
/** 过滤器: * File类中有两个和listFiles方法重载的方法,方法的参数就是过滤器 * listFiles(FileFilter filter) * java.io.FileFilter ...
 - LoadRunner内部结构(2)
			
LoadRunner内部结构(2) 接着(1)的内容: 17.默认的LRReport文件夹创建在本地分析机器的My Documents文件夹下来存储分析会话文件. 18.可以使用HTML格式 19.格 ...
 - 手把手教你接口自动化测试 – SoapUI & Groovy【转】
			
手把手教你接口自动化测试 – SoapUI & Groovy Posted on 2015-01-21 09:38 WadeXu 阅读(12741) 评论(10) 编辑 收藏 手把手教你接口自 ...
 - thinkphp 区间查询
			
ThinkPHP支持对某个字段的区间查询,例如: 富瑞华大理石平台厂家哪家好 $map['id'] = array(array('gt',1),array('lt',10)) ; 得到的查询条件是: ...
 - duilib教程之duilib入门简明教程4.响应按钮事件
			
上一个Hello World的教程里有一句代码是这样的:CControlUI *pWnd = new CButtonUI; 也就是说,其实那整块绿色背景区域都是按钮的区域.(这里简要介绍下,CC ...
 - arguments介绍(二)
			
1.1 将参数从一个函数传递到另一个函数 下面是将参数从一个函数传递到另一个函数的推荐做法. function foo() { bar.apply(this, arguments); } functi ...
 - VS2010-MFC(对话框:创建对话框模板和修改对话框属性)
			
转自:http://www.jizhuomi.com/software/149.html 对话框,大家应该很熟悉了,在我们常用的软件中大多都有对话框界面,例如,360安全卫士的主界面其实就是个对话框, ...
 - 转:Wireshark基本介绍和学习TCP三次握手
			
源地址:http://www.cnblogs.com/TankXiao/archive/2012/10/10/2711777.html 之前写过一篇博客:用 Fiddler 来调试HTTP,HTTPS ...