我正在尝试学习 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 之后。