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