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分叉发生在fork()原语内部。

你可以想象一下,在代码中fork,系统调用实际上复制了该过程并在同一点开始执行,但略有不同:

  • 父进程fork函数将返回子进程的进程ID
  • 子进程fork函数将返回0。

因此,你知道自己在编程过程中处于什么位置,例如

  if (fork())
  {
     printf("Parent speaking\n");
     // parent's tasks
  }
  else
  {
     printf("Child here\n");
     // child's tasks
  }

答案2

fork() 将复制分叉的进程状态目前在.*

很难说子进程在哪一行代码中启动,你真的必须查看反汇编的编译版本才能理解。但通常可以假设它在调用 fork 之后启动,当然在你的情况下。

它复制了所有变量、堆栈,整个东西(实际上是内存中的空间)被逐字节复制。唯一改变的是进程 ID**。

如果你这样做:

int i = random_integer();
fork();

i子进程将具有与其父进程相同的值。

*:在子进程中,fork()的返回值将为0,而不是进程ID。

**:此外,子进程不会有父母的锁和资源利用。

答案3

子进程在fork()调用后立即开始执行。更具体地说,在 fork() 返回子进程 ID 或 0 之后。

相关内容