当我运行以下代码时
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
int main()
{
pid_t pid;
pid = vfork();
printf("hello worldn");
}
Output:
hello world
hello world
hello world
Segmentation fault
我知道,除非调用exec((或_exit((,否则如果我们试图修改任何变量,vfork((的行为可能会很奇怪,但有人能解释一下到底发生了什么吗??为什么《你好世界》被印了三次?是因为printf((被缓冲了吗?最后,为什么在父级试图返回时会发生seg错误?
(来自POSIX.1(vfork((函数具有与fork(2(相同的效果,除了如果由创建的进程vfork((修改pid_t类型变量以外的任何数据用于存储vfork((的返回值,或从调用vfork((的函数,或调用任何其他函数在成功调用_exit(2(或的exec(3(家族之一之前功能。
似乎违反了所有使用vfork的条件。那么它就不起作用了。
我写的这段代码是一场灾难,将以未定义的方式运行,但对这种行为的合理解释可能是:-
由于地址空间是共享的,并且当子级不是通过_exit()
或exec()
返回时,因此将执行I/O缓冲区的刷新(这会导致额外的hello-world语句(,并且在清理过程中,当释放到printf()
的内存时,它可能会在堆栈帧上进行函数调用,而父级仍然处于停滞状态。返回后,父级可能在堆栈上没有任何返回地址可返回给任何人,这会导致分段错误。