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

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

我正在尝试学习 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);
}

输出是:

This is most definitely the parent process  
Which process printed this?  
Which process printed this?

我认为这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 ());

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

答案1

新进程将在调用中创建fork(),并将像父进程一样从它返回开始。返回值(您存储在 中retvalfork()将为:

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

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

答案2

我认为 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 */
}

执行流程为:

caller process     fork() → ...
original program            exec() → 2 → 3 → 4 → 5 → 6
forked program                                   5 → 6

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

如果您想知道原始程序和分叉程序的行为可能有何不同,因为它们必然共享相同的代码,请参阅迈克尔·莫罗泽克的回答。

答案3

真正的解决办法是

switch (fork()) {
    case -1 :
        fprintf (stderr, "fork failed (%s)\n", strerror(errno));
        break;
    case 0 :  // child process comes here
        break;
    default : // parent process
        break;
}

// all continue here

答案4

无论 , 之后的代码都fork()被复制到子进程中,并且不要混淆父进程和子进程,它们是两个不同的实体,具有相同的(重复的,不是共享的)环境。

现在看看你的输出...

相关内容