【问题标题】:Trying to understand the logic of fork function return value试图理解fork函数返回值的逻辑
【发布时间】:2017-12-13 21:38:33
【问题描述】:

考虑这个简单的程序:

using namespace std;

int main(int argc, const char * argv[]) {
    cout << "first pid: " << getpid() << endl;
    int a = fork();
    int b = fork();
    cout << a << " " << b << endl;
    return 0;
}

所以我一遍又一遍地运行它,并试图了解每次运行中出现的模式是什么。我根本不明白数字方面发生了什么。我最初在分叉之前打印了 pid,然后我再也看不到那个 pid,就好像它被改变了一样。我添加了 2 个不同的输出以供参考:

first pid: 64538
64541 64542
64541 0
0 64543
0 0

first pid: 64625
64628 64629
0 64630
0 0
64628 0

我所理解的是,现在有 4 个进程处于活动状态,因为第一个分叉产生 2 个进程,而第二个分叉将它们分叉成 4 个进程。 我不明白的是打印到控制台的 ID 的逻辑。

【问题讨论】:

  • 由于子进程未同步,它们以随机顺序打印。
  • ID 由操作系统分配,因为它有自己的内在“逻辑”。必须(由操作系统)授予 ID 是唯一的,但除此之外(接受应该有一个特殊的 No-PID 值)。
  • 第一个输出中的 64541 和第二个输出中的 64628 出现两次。 unix 系统上的 PID 通常按升序分配。
  • 要记住的重要一点是fork 是唯一会返回两次 的函数:一次在父项中,一次在子项中。在子进程fork 返回0。而且由于您的进程之间没有同步,因此一个进程可能会在另一个进程到达第二个fork 调用之前运行完成,这意味着进程 ID 可以重复使用。
  • 0 0 由第二个 fork() 的子进程打印,该子进程是第一个 fork() 的子进程。 !0 !0 由第二个 fork() 的父进程打印,它是第一个 fork() 中的父进程...

标签: c++ linux operating-system


【解决方案1】:

下面是正在发生的事情的表格:

gen_0     | gen_1         | gen_2_0       | gen_2_1
          |               |               |
==[ before first fork ]==================================
started   |               |               |
pid = 123 |               |               |
          |               |               |
--[ after first fork ]===================================
          | started       |               |
          | pid = 1111    |               |
          | parent: gen_0 |               |
a = 1111  | a = 0         |               |
          |               |               |
--[ after second fork ]==================================
          |               | started       | started
          |               | pid = 2222    | pid = 3333
          |               | parent: gen_0 | parent: gen_1
a = 1111  | a = 0         | a = 1111      | a = 0
b = 2222  | b = 3333      | b = 0         | b = 0

【讨论】:

    【解决方案2】:

    我在 OP 中添加了 cmets 来描述发生了什么:

    using namespace std;
    
    int main(int argc, const char * argv[]) {
        cout << "first pid: " << getpid() << endl;
        int a = fork();
        // from here two processes run:
        // in parent a is PID of child
        // in child a is 0
        int b = fork();
        // from here four processes run:
        // a is for parent and child identical 0 or PID
        // in parents b is PID of child
        // in children b is 0
        // Thus, the following shows all 4 combinations of 0 and not 0.
        cout << a << " " << b << endl;
        return 0;
    }
    

    【讨论】:

      【解决方案3】:

      “逻辑”是零表示您是 fork() 的孩子,-1 表示错误,任何正数是孩子的 PID,您是父母。

      对于如何分配 PID,没有指定的“逻辑”。不用找。

      【讨论】:

      • 虽然有一种模式,在每次运行中都有一个进程打印 2 个非 0 的数字,其余的打印 1 或 2 个零。对此有何解释?
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2020-03-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-04-24
      • 1970-01-01
      • 2022-12-07
      相关资源
      最近更新 更多