vfork永远不会回来

时间:2011-07-13 08:54:20

标签: c linux fork

为什么这个程序永远不会返回并继续创建子进程?

int main()
{
    pid_t pid;
    int foo1 = 1, foo2 = 2;
    printf("before fork()\n");

    if ((pid = vfork()) < 0 ) {
            printf("fork failed.\n");
    }else if (pid == 0) {
            foo1++;
            foo2++;
            printf("child process: pid is %d, my parent pid is  %d\n", getpid(), getppid());
    }else if (pid > 0){
            printf("parent process: pid is %d\n", getpid());
    }

    printf("%s: foo1 is %d, foo2 is %d\n",pid == 0 ? "child process" : "parent process", foo1, foo2);
    return 0;
}

输出如下:

before fork()
child process: pid is 17244, my parent pid is  15839
child process: foo1 is 2, foo2 is 3
parent process: pid is 15839
parent process: foo1 is -1079005816, foo2 is -1218256081
before fork()
child process: pid is 17245, my parent pid is  15839
child process: foo1 is 2, foo2 is 3
parent process: pid is 15839
parent process: foo1 is -1079005816, foo2 is -1218256081
before fork()
.....
.....

如果在第二个if块中添加一个_exit,那么它就是它。 我知道vfork与父进程共享相同的地址空间,但是如果progrem以崩溃而不是无限循环结束则更合理。

3 个答案:

答案 0 :(得分:4)

vfork是一个非常棘手的系统调用,其唯一的用途是立即在孩子中使用execve - 对于其他类型的用途,它是危险且不可预测的。

另请注意,与fork不同,父级会暂停,直到孩子退出或致电execve

答案 1 :(得分:1)

来自手册:

如果由vfork()创建的进程修改除了用于存储vfork()的返回值的pid_t类型的变量之外的任何数据,或者从调用vfork()的函数返回,则行为是未定义的,或在成功调用_exit()或exec系列函数之前调用任何其他函数。

因为父和子共享地址空间,所以不能从调用vfork()的函数返回; 这样做可能会破坏父级的堆栈

答案 2 :(得分:0)

在vfork子项中,你只能调用函数来安全地调用信号处理程序,因此来自vfork内部的printf是个坏主意。