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;  } 

运行结果:

[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

为什么两条语 都会打印呢?这是因为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());elseprintf("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;
}

[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 

本来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;  } 

如果没有_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 

转载于:https://www.cnblogs.com/yeanz/p/9600382.html

【转】vfork 和 fork的区别相关推荐

  1. linux---谈谈vfork和fork的区别及exit与return

    fork():创建子进程的函数,是大家比较熟悉的吧.pid_t id = fork(); 这里的vfork();也是创建子进程的函数.现在我们来剖析一下它们吧. 第一例: 先看一个fork()的例子哦 ...

  2. Linux C 中vfork和fork的区别

    我们知道, fork会创建一个新的进程, 这个新的进程是当前进程的子进程, 区别在于, fork函数会复制父进程的一些资源, 也就是, 仅仅是复制的关系, 而非共享. 而vfork就不同了, 利用vf ...

  3. Linux系统编程(vfork和fork)

    文章目录 前言 一.vfork讲解 二.vfork使用 三.exit和_exit 1.exit和_exit对比 2.在vfork中的使用 四.vfork和fork区别 总结 前言 本篇文章讲解vfor ...

  4. linux c之创建进程fork和vfork函数之间的区别

    1.函数简介 1).得到当前的进程id pid_t getpid(); 2).fork函数 要创建进程,必须调用fork函数, 系统调用fork用于派生一个进程,函数原型如下 #include< ...

  5. clone和fork的区别linux,fork clone 和 fork 的区别

    分类: Linux系统 C++2010-08-27 09:51 34人阅读 评论(0) 收藏 举报 首先说明Linux下的进程与线程比较相近.这么说的一个原因是它们都需要相同的数据结构来表示,即tas ...

  6. git fork clone 区别_Working with Git | Git 与 GitHub

    关于 各位好,这里是 China's Prices Project 项目的知乎专栏.关于 CPP 项目,您可以在这篇文章里了解到更多的信息.若您对这个项目感兴趣,我们非常欢迎您与我们交流您的想法与见解 ...

  7. git fork clone 区别_我的Git笔记

    每次用到git,总会遇到一些问题,所以写这篇文章记录一下. fork 等fork完之后,你可以在自己的仓库中看到同名的项目,URL的形式:https://github.com/your_name/re ...

  8. clone 和 fork 的区别

    fork()是全部复制 vfork()是共享内存 clone()是可以将父进程资源有选择地复制给子进程,而没有复制的数据结构则通过指针的复制让子进程共享,具体要复制哪些资源给子进程,由参数列表中的cl ...

  9. 【Linux进程、线程、任务调度】二 fork/vfork与写时拷贝 线程的本质 托孤 进程睡眠和等待队列

    学习交流加(可免费帮忙下载CSDN资源): 个人微信: liu1126137994 学习交流资源分享qq群1(已满): 962535112 学习交流资源分享qq群2(已满): 780902027 学习 ...

最新文章

  1. 《OpenCV3编程入门》学习笔记7 图像变换(一)基于OpenCV的边缘检测
  2. 用python画烟花-用python做一个烟花show
  3. 如何做好仓库管理的工作专业知识
  4. coverage.py - python 单元测试覆盖率统计工具
  5. 选项卡,下拉菜单操做时的页面数据更新,highcharts,d3 结合。
  6. python可选参数定义_c#教程之定义可选参数
  7. 344.Reverse String
  8. 求助大神!ROST EA情感分析软件情感词典如何更新
  9. 【qq视频录像机软件2013V3.0】聊天视频网络电视录像专家
  10. Mindspore实现手写字体识别
  11. 基于微信小程序会议室预约系统设计与实现毕业设计毕设开题报告参考
  12. 如何建设研发部门体系,理清责任和关系
  13. 建立集群——rsh(remote shell)实现无密码访问
  14. glove.840B.300d glove词向量词嵌入文件国内服务器下载 出现麻烦阻塞的点时,就要思考google有没有更快捷的方法
  15. LeetCode笔记05:最长公共前缀
  16. PYNQ2之ZYNQ的PS读写DDR
  17. spring boot基础简介
  18. ROS2入门教程—理解话题(Topic)
  19. XGBoost目标函数推导
  20. 秋招历险记-深度学习

热门文章

  1. 互联网人年终总结扎心指南
  2. 2021 互联网大厂新年礼盒大比拼!
  3. 我酸了!又是别人家公司!百度新年发 U 奖金鼓励员工
  4. 后疫情时代下,企业数字化转型之路如何走?
  5. rsync同步服务实验讲解
  6. 图像通道、Scalar、分离、合成通道
  7. Linux学习之路4——文件IO打开、创建、读写操作
  8. GitHub的MySQL高可用性实践
  9. java中String,int,Integer,char、double类型转换
  10. Azure手把手系列5:Azure帐户和订阅