【问题标题】:Fork() in an IF statment in UNIXFork() 在 UNIX 中的 IF 语句中
【发布时间】:2019-07-06 15:44:43
【问题描述】:

我对 fork() 的理解是,一旦它创建了子进程,它就对我们到达“fork()”之前存在的代码一无所知。 但是在具有多个 fork() 的 if 语句中,似乎子进程正在执行参数计算,即使它出现在它的 fork() 创建者之前。

例如:

int main ()
{
if((fork())==(fork()))
   printf ("Hello.\n");

printf ("Bye.\n");
return 1;
}

将有包括父亲在内的4个进程的总和。在由另一个子进程创建的子进程(我将其称为 d)中,创建我们的 d 进程的 fork() 是 if 语句中的第二个 fork()。

尽管第一个 fork() 对 d 不熟悉,但我的理解是 d 进程计算出 0==0 并打印“Hello”(输出肯定是正确的)。我有两个问题:

1.d 进程是如何到达创建这个 d 进程(第二个)的 fork() 之前的 if 语句中的第一个 fork() 的?

2.为什么我们在 d 进程中的第一个 fork() 等于 0,如果它只发生在由这个特定的 fork()(d 的父亲)创建的子进程中?

【问题讨论】:

  • “一旦它创建了子进程,它就对我们到达'fork()'之前存在的代码一无所知” 为什么/如何?你能更详细地解释你的信念吗?
  • 我的理解是子进程应该开始在fork()之后的代码上运行,我认为它不应该对它之前的代码做任何事情..
  • 进程已被克隆。它在内存中具有相同数据的同一程序中的同一点(fork() 调用的返回值除外)。为什么它的历史将不可用,那么它如何能够在新进程中继续执行该程序?它会做什么?
  • 这是非常可靠的观点,我只是在学习这个对我来说是新的主题

标签: unix fork


【解决方案1】:

我对 fork() 的理解是,一旦在其中创建的子进程对该点之前存在的代码一无所知,我们就会到达“fork()”。

除了返回值fork() 之外,子代是父代的精确复制品。这包括所有运行时状态,包括内存和 CPU 寄存器。这就是进程拥有的所有内存,所以它们“记住”相同的东西。

让我们像这样重写你的程序:

#include <stdio.h>
#include <unistd.h>

int main(void)
{
    pid_t a = fork();
    pid_t b = fork();
    if (a == b)
        printf ("Hello.\n");
    printf ("Bye.\n");
    return 1;
}

分叉之后,有四个进程,原来的一个有a != 0 &amp;&amp; b != 0(和a != b,因为它的两个孩子是不同的),另外两个有ab之一,零,第四个有a == b == 0。最后一个是a == b 的唯一一个,因此它运行有条件的printf() 调用。

【讨论】:

  • 所以,它记得在他创建之前的状态下,第一个 fork()(他的父亲 fork())等于 0 ?是否有责任在 if 语句之后检查,即使通常我们不会在 fork () 之前回顾之前的代码?
  • @BenJ,是的。在调用第二个fork() 时,第一个的返回值存储在进程的内存或寄存器中的某个位置。 (无论是存储到命名变量还是未命名的临时值,该值都需要在某个地方才能进行比较)
  • 他有责任在 if 语句之后检查,即使通常我们不会在 fork() 之前回顾之前的代码?
  • @BenJ,我不确定你的第二个问题是什么意思
  • @BenJ,是的,它们都运行相同的代码,只是 PID 的 ab 的值不同。您可以在if 之前放置printf("%d %d\n", (int) a, (int) b) 之类的内容,您会看到它们的值。 (这当然只适用于命名变量,不同进程的输出行会混在一起)
猜你喜欢
  • 2012-09-07
  • 1970-01-01
  • 2020-04-02
  • 2010-09-21
  • 2013-09-25
  • 2013-11-17
  • 1970-01-01
  • 1970-01-01
  • 2015-06-16
相关资源
最近更新 更多