进程的创建之vfork()

  • 蓝蓝的天
  • LV5工程师
  • |      2016-07-05 17:43:18
  • 浏览量 394
  • 回复:1
本帖最后由 蓝蓝的天 于 2016-7-5 18:03 编辑 在早期的实现中,fork没有实现写时拷贝机制,而是直接对父进程的数据段,堆和栈 进行完全拷贝,效率十分低下。很多程序在fork一个子进程后,会紧接着执行E x e c 家族函数,这更是一种浪费。所以BSD引入了vfork。既然fork之后会执行E x e c函数,拷贝 父进程的内存数据就没有意义了,所以引入的vfork压根就不会拷贝父进程的内存数据, 而是直接共享。再后来Linux引入了写时拷贝的机制,其效率提高了很多,这样一来, vfork其实就可以退出历史舞台了。 vfork会创建一个子进程,该子进程会共享父进程的内存数据,而且系统将保证子进程 先于父进程获得调度。子进程也会共享父进程的地址空间,而父进程将被一直挂起,直到 子进程退出或执行e x ec。 注意,vfork之后,子进程如果返回,则不要调用return,而应该使用_exit函数。如果 使用return,就会出现诡异的错误。请看下面的示例代码: 编译: 运行: 调用子进程,如果使用return返回,就意味着main函数返回了,因为栈是父子进程 共享的,所以程序的函数栈发生了变化。main函数return之后,通常会调用exit系的 函数,父进程收到子进程的exit之后,就开始从vfork返回,但是这时整个main函数 的栈都已经不复存在了,所以父进程压根无法执行。于是会返回一个诡异的栈地址。 作为对比,改成用_exit函数返回,代码如下; 编译运行: 可以看到,运行结果正确,也不报错了。
  • 0
  • 收藏
  • 举报
  • 分享
我来回复

登录后可评论,请 登录注册

所有回答 数量:1
兵临城下 2016-07-05
我还是喜欢用线程。
0   回复
举报
发布
x
收藏成功!点击 我的收藏 查看收藏的全部帖子