Linux进程创建函数vfork简介

来源:互联网 发布:网络测试员是干什么的 编辑:程序博客网 时间:2024/05/08 10:09

基础知识

vfork和fork的区别和联系

vfork用于创建一个新进程,而该新进程的目的是exec一个新程序。vfork与fork都创建一 个子进程,但它不将父进程的地址空间复制到子进程中,

因为子进程会立即调用 exec,于是不会存访问该地址空间。

相反,在子进程调用exec或exit之前,它在父进程的空间中运行,也就是说会更改父进程的数据段、栈和堆。另一个区别是vfork保证子进程先运行,父进程在运行。但是fork创建的两个进程的运行顺序则不知道,由进程调度器决定。

先来通过一个简单的小程序来看看vfork的工作


运行结果



接下来看一个奇妙的现象,看看这段程序只是修改了一个地方,(将exit改为return)为什么挂掉了呢??


运行结果



接下来就开始分析为什么程序会挂掉?

从上面我们知道,结束子进程的调用是exit()而不是return,如果你在vfork中return了,那么,这就意味main()函数return了,注意因为函数栈父子进程共享,所以整个程序的栈就跪了。

如果你在子进程中return,那么基本是下面的过程:

1)子进程的main() 函数 return了,于是程序的函数栈发生了变化。

2)而main()函数return后,通常会调用 exit()或相似的函数(如:_exit(),exitgroup())

3)这时,父进程收到子进程exit(),开始从vfork返回,但是父进程栈都被子进程给return干废掉了,你让我怎么执行?(注:栈会返回一个诡异一个栈地址,对于某些内核版本的实现,直接报“栈错误”就给跪了,然而,对于某些内核版本的实现,于是有可能会再次调用main(),于是进入了一个无限循环的结果,直到vfork 调用返回 error)

好了,现在再回到 return 和 exit,return会释放局部变量,并弹栈,回到上级函数执行。exit直接退掉。return会调用局部对象的析构函数,exit不会。

可见,子进程调用exit() 没有修改函数栈,所以,父进程得以顺利执行


1 0
原创粉丝点击