在vfork系统调用中,父进程和子进程共享页面,子进程对全局变量的任何更改(比如说)都会在返回后反映到父进程。现在,如果我们从子进程执行exec()系统调用,它会将指定的程序加载到子进程的地址空间,当父进程再次变为活动时,它不会发现损坏的数据和堆栈帧(由子进程加载的新二进制文件)? 请回复,
答案 0 :(得分:0)
不,内核安排这不是问题。我不再记得确切的细节,但一般程序是:当进程调用vfork
时,内核保存堆栈指针和PC,并为子进程执行部分设置。当一个调用vfork
的进程调用execve
时,内核会为新程序映像创建一个新的地址空间,而不是覆盖调用进程的地址空间。然后它将父级的堆栈指针和PC恢复为以前的状态,父级继续从vfork
开始。
vfork
的在线联机帮助令人失望,并且往往对其危险性和缺乏实用性发表讽刺性评论,这是不公平的 - 它实际上比fork
更有效,即使是复制 - 写入地址空间共享,因为它不需要刷新TLB或在内核中执行几乎相同的工作,并且其语义在仍然广泛使用的操作系统中相当一致。错误处理是一个痛苦的问题,但如果你认真对待它,那么使用普通fork
进行错误处理同样糟糕。
[有谁知道在vfork
和execve
之间进行I / O重定向设置是否安全?该标准并不保证,并且联机帮助文件也不保证,但我的回忆是,该窗口中的打开/关闭/重复操作仅影响未成年人,例如fork
。]