操作系统概念和APUE说
通过vfork(),父进程被挂起,子进程使用父进程的地址空间。由于vfork()不使用写时复制,因此,如果子进程更改了父级地址空间的任何页面,则父级恢复后,更改后的页面将对父级可见。因此,必须谨慎使用vfork()以确保子进程不会修改父进程的地址空间。
vfork()旨在在子进程创建后立即调用exec()或exit()时使用。
我如何理解最后一句话?
当通过vfork()
调用创建子进程时exec()
,是否exec()
通过加载新程序来修改父进程的地址空间?
当通过vfork()
调用创建子进程时,终止子进程时exit()
是否exit()
不修改父进程的地址空间?
我偏爱Linux。
谢谢。
当通过
vfork()
调用创建子进程时exec()
,是否exec()
通过加载新程序来修改父进程的地址空间?
不,exec()
为新程序提供新的地址空间;它不会修改父地址空间。例如,exec
请参见有关POSIX中功能的讨论和Linuxexecve()
联机帮助页。
当由vfork()创建的子进程调用exit()时,终止子进程时exit()是否不会修改父进程的地址空间吗?
Plainexit()
可能会–运行由正在运行的程序(包括其库)安装的出口挂钩。vfork()
更严格;因此,在Linux上,它要求的使用_exit()
它不调用C库的清理功能。
vfork()
事实证明,很难做到正确;在POSIX标准的当前版本中已将其删除,posix_spawn()
应改为使用。
但是,除非你真的知道你在做什么,你应该没有任何使用vfork()
或posix_spawn()
; 坚持好老fork()
和好exec()
。
上面链接的Linux联机帮助页提供了更多上下文:
但是,在糟糕的过去
fork(2)
,通常需要在不必要的情况下完全复制调用方的数据空间,因为通常在此之后立即exec(3)
进行一次。因此,为了提高效率,BSD引入了vfork()
系统调用,该系统调用没有完全复制父进程的地址空间,而是借用了父进程的内存和控制线程,直到execve(2)
发生了对调用或退出的调用。当孩子使用其资源时,父进程被暂停。的使用vfork()
非常棘手:例如,在父进程中不修改数据取决于知道哪些变量保存在寄存器中。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句