在 fork() 之后,子进程从哪里开始执行?

24 process c fork api

我正在尝试学习 UNIX 编程,但遇到了一个关于 fork() 的问题。我知道 fork() 创建了一个与当前正在运行的进程相同的进程,但是它从哪里开始呢?例如,如果我有代码

int main (int argc, char **argv)
{
    int retval;
    printf ("This is most definitely the parent process\n");
    fflush (stdout);
    retval = fork ();
    printf ("Which process printed this?\n");

    return (EXIT_SUCCESS);
}
Run Code Online (Sandbox Code Playgroud)

输出是:

这绝对是父进程
哪个进程打印了这个?
哪个过程打印了这个?

我认为这fork()会创建一个相同的过程,所以我最初认为在该程序中,该fork()调用将永远递归调用。我猜是fork()fork()通话后从头创建的新进程?

如果我添加以下代码,以区分父进程和子进程,

if (child_pid = fork ()) printf ("This is the parent, child pid is %d\n", child_pid);
else printf ("This is the child, pid is %d\n",getpid ());
Run Code Online (Sandbox Code Playgroud)

在 fork() 调用之后,子进程从哪里开始执行?

Mic*_*zek 25

新进程将在fork()调用中创建,并且会像父进程一样从它返回开始。返回值(您存储在 中retval)来自fork()

  • 0 在子进程中
  • 父进程中子进程的PID
  • -1 如果失败则在父级中(自然没有子级)

您的测试代码工作正常;它存储来自fork()in的返回值child_pid并用于if检查它是否为 0(尽管它不检查错误)


bad*_*adp 14

我认为 fork() 创建了一个相同的进程,所以我最初认为在那个程序中,fork() 调用将永远递归调用。我猜从 fork() 创建的新进程在 fork() 调用之后启动?

是的。让我们对行进行编号:

int main (int argc, char **argv)
{
    int retval;                                               /* 1 */
    printf ("This is most definitely the parent process\n");  /* 2 */
    fflush (stdout);                                          /* 3 */
    retval = fork ();                                         /* 4 */
    printf ("Which process printed this?\n");                 /* 5 */
    return (EXIT_SUCCESS);                                    /* 6 */
}
Run Code Online (Sandbox Code Playgroud)

执行流程为:

caller process     fork() ? ...
                          ?
original program            exec() ? 2 ? 3 ? 4 ? 5 ? 6
                                               ?
forked program                                   5 ? 6
Run Code Online (Sandbox Code Playgroud)

...它准确地解释了您收到的输出。

如果您想知道原始程序和分叉程序的行为可能有何不同,因为它们必须共享相同的代码,请参阅Michael Mrozek 的回答。

  • 我可以评论说那些对角线箭头是*棒的*。 (11认同)