c - vfork() 调用后退出和返回之间的区别

标签 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;
}

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

___________befor fork______________.
child
pid: 4370, ppid: 4369
parent
pid: 4369, ppid: 2924

如果我使用 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 ...

我知道您不能在 vfork() 函数之后的子进程中使用 return。 但是我不明白为什么父级在 return 调用后没有结束?

谢谢。

最佳答案

从子函数返回是无效的,因为 vfork() 父子共享同一个栈,返回子函数会弄乱栈帧 parent 。通常调用 main()(在 start 函数中)之后是调用 exit() 或类似的,所以调用 exit() 在子进程中将覆盖调用 main() 所使用的堆栈空间(并且仍在父进程中使用)。因此,当子进程确实退出时,父进程将从 vfork() 返回,但堆栈上的返回地址可能会被破坏,因此它可以返回到任何地址或执行任何操作。

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

关于c - vfork() 调用后退出和返回之间的区别,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7676619/

相关文章:

c - 等待 child 完成

在 c 中创建一个具有超过 1 个动态大小数组的结构?

c - 为什么输出包含 4 个 0?

c - WEXITSTATUS(status) 返回什么?

python - 了解 os.fork 和 Queue.Queue

ruby-on-rails - Ruby on Rails 超时。我如何 fork 一个进程?

c - 按位进位应用

C - 数组在放入变量时从同一元素返回不同的值

linux - shmget() 返回的 shmid 是否跨进程唯一?

c - 我的客户端无法正确发送到服务器