vfork创建的子进程与父进程地址空间关系
来源:互联网 发布:最大的淘宝代运营 编辑:程序博客网 时间:2024/05/07 03:00
在《UNIX环境高级编程》一书的第八章中,有一道课后习题如下:
回忆图7-3典型的存储空间布局。由于对应于每个函数调用的栈帧通常存储在栈中,并在调用 vfork后,子进程运行在父进程的地址空间中,如果不是在main函数中而是在另一个函数中调用vfork,以后子进程从该函数返回时,将会发生什么情况?
作者Rich Stevens是一位大师,留下这么一题必有其深意,于是结合《深入理解计算机系统》中的知识,写了个程序验证了下,受益良多。
首先回忆下程序运行的栈帧结构(见下图):
从图中可知,如果一个函数调用用了另外一个函数,那么被调用者的栈帧则会被压入栈顶被设置为“当前帧”,首先执行被调用者,执行完成后,调用者的栈帧被弹出程序栈,然后从“返回地址”返回到调用者的地址空间中。
于是猜想,如果在main函数中,调用了一个函数foo,则“当前帧”为foo的栈帧,这时,若调用vfork创建一个子进程,那么根据vfork的语义,子进程不会完全复制父进程的地址空间,它会在父进程的地址空间中运行(这也是为什么vfork能保证子进程先运行,而fork不能保证。因为vfork创建的子进程是与父进程共享地址空间,为了避免竞争,所以就让子进程先运行,而父进程后运行;而fork创建的子进程是父进程的副本,所以不会带来竞争问题,谁先谁后也就无所谓了),所以它共享的是“当前帧”的地址空间,因此当子进程返回时,只会改变foo的数据,而不会改变main栈帧中的数据。
下面就来写个程序验证一下:
运行此程序,得到结果为(见下图):
果然,可以看到在foo和main中,进程号都是一样的,也就说明foo和main在同一进程中。但是各个变量的值却有差异:在foo返回后mian函数中的局部变量var依然是初始值,并没有增加,推其原因,就是因为子进程共享的是foo的栈帧数据,而非main函数的栈帧,所以自然也就不会改变main栈帧中的数据。
书中正文中说:子进程不会完全复制父进程的地址空间,它会在父进程的地址空间中运行。因此可以进一步得出一个结论:vfork创建的子进程,共享的是父进程当前栈帧的地址空间。
- vfork创建的子进程与父进程地址空间关系
- vfork创建的子进程与父进程地址空间关系
- fork vfork 父进程和子进程的内存关系
- vfork()系统调用-创建子进程,阻塞父进程
- fork与vfork创建进程的区别
- 进程地址空间的创建
- 创建子进程时变量的地址与父进程一样而数值不一样的问题
- linux之fork,vfork创建子进程
- fork,vfork,clone创建子进程用法
- fork()后父子进程的地址空间
- Linux中,子进程与父进程的继承关系
- 子进程不会完全复制父进程的地址空间,它会在父进程的地址空间中运行
- 进程创建fork与vfork,孤儿进程,僵尸进程
- C进程创建fork与vfork的区别
- 创建和删除进程的地址空间
- linux 进程创建clone、fork与vfork
- Linux进程创建fork()与vfork()
- linux 进程创建clone、fork与vfork
- Transactions、Magazines、Journals和Proceedings的区别
- 【编程游戏】贺岁霓虹灯。(参观345楼KiteGirl的霓虹灯,VBScript编写)
- vbscript实现javascript “this” 的功能
- 新手报道
- 问题1
- vfork创建的子进程与父进程地址空间关系
- 短小精悍的线性时间素数筛法
- 2010年现首批30岁‘80’后近半无房无车
- 子类重写父类的构造函数
- Javascript身份证号校验
- UVa Online Judge - Volume I 题目和解答索引
- 创业者
- 测试 Google Gadget
- CodeSmith API 中文版-最新整理