vfork() 调用后退出和返回的区别

nic*_*ick 5 c posix fork multiprocessing

我有一个行为未定义的程序( vfork() 使用不当):

#include <stdio.h>
#include <unistd.h>
#include <errno.h>

int main ( int argc, char *argv[] )
{
    pid_t pid;
    printf("___________befor fork______________.\n");
    if((pid=vfork()) < 0)
        perror("fork");
    else if(pid > 0)
        printf("parent\n");
    else
        printf("child\n");

    printf("pid: %d, ppid: %d\n", getpid(), getppid());

    //exit(0);
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

如果我使用exit(0)函数而不是返回 - 输出是:

___________befor fork______________.
child
pid: 4370, ppid: 4369
parent
pid: 4369, ppid: 2924
Run Code Online (Sandbox Code Playgroud)

如果我使用return 0- 我会得到这样的无限输出:

___________befor fork______________.
child
pid: 4455, ppid: 4454
parent
pid: 4454, ppid: 2924
___________befor fork______________.
child
pid: 4456, ppid: 4454
parent
pid: 4454, ppid: 2924
___________befor fork______________.
child
pid: 4457, ppid: 4454
parent
pid: 4454, ppid: 2924
    and so on ...
Run Code Online (Sandbox Code Playgroud)

我知道你不能return在子函数后使用vfork()。但我不明白为什么父母在return通话后没有结束?

谢谢。

mar*_*k4o 5

从子进程中的函数返回是无效的,因为vfork()父进程和子进程共享相同的堆栈,在子进程中返回会弄乱父进程的堆栈框架。通常调用main()(在 start 函数中)之后是调用exit()或类似的调用,这样exit()子调用中的调用将覆盖调用main()使用(并且仍在父调用中)的相同堆栈空间。因此,当子进程退出时,父进程将返回,vfork()但堆栈上的返回地址可能会被破坏,因此它可以返回到任何地址或做任何事情。

此外,在孩子中,如果您不执行 exec 您应该调用_exit()而不是exit(). exit()将刷新 stdio 输出缓冲区,但这些相同的缓冲区由父级管理,而_exit()只会结束进程。