【问题标题】:Variable values in Fork() childFork() 子中的变量值
【发布时间】:2011-05-26 07:12:45
【问题描述】:

我已经问过一个关于 fork() 的问题,这是另一个问题。 给定以下代码:

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

int main()
{
    pid_t pid1, pid2;
    pid1 = fork();
    pid2 = fork();
    if (pid1 != 0 && pid2 != 0)
        printf("A\n");
    if (pid1 != 0 || pid2 != 0)
        printf("B\n");
    exit(0);
}

在第二个fork() 之后,pid1pid2 的值是多少?
据了解,第一个 fork 设置 pid1 &gt; 0 并且在以后创建的所有子代中都是相同的。但是,pid2 会发生什么?

谢谢!

【问题讨论】:

    标签: c++ c unix


    【解决方案1】:

    你所要做的就是尝试一下:

    #include <unistd.h>
    #include <stdio.h>
    int main (void) {
        pid_t pid1 = -1, pid2 = -1;
        pid1 = fork();
        pid2 = fork();
        printf ("%5d/%5d: %5d %5d\n", getpid(), getppid(), pid1, pid2);
        sleep (5); // to prevent inheritance by init process on parent death
        return 0;
    }
    

    你会看到:

      PID/ PPID   pid1  pid2
     ----------   ----  ----
     2507/ 2386:  2508  2509      first process
     2508/ 2507:     0  2510      first fork from 'first process'
     2509/ 2507:  2508     0      second fork from 'first process'
     2510/ 2508:     0     0      second fork from "first fork from 'first process'"
    

    换句话说:

    • 第一个进程 2507 将 pid1pid2 设置为其两个子进程。
    • 第二个进程 2508 的 pid1 为 0,因为它是该分叉中的子进程,但 pid2 为 2510,因为它是 那个分叉中的父进程。
    • 第三个进程 2509 从第一个进程(它的父进程)继承pid1,因为它在 已设置之后分叉。它的 pid2 为 0,因为它是第二个 fork 中的孩子。
    • 第四个进程 2510 从 second 进程(它的父进程)继承pid1,因为它在设置之后分叉。它的pid2 也是 0,因为它是第二个 fork 中的孩子。

    【讨论】:

      【解决方案2】:

      我正要为你测试,但让我告诉你我的期望。

      / pid2=[child3 pid] { pid1 = child1;pid2 = child3;} pid1=[child1 pid] fork() / \ / pid2=0 { pid1 = child1;pid2 = 0;} 叉() \ pid2=[child2 pid] { pid1 = 0; pid2 = child2;} \ / pid1=0 - fork() \ pid2=0 { pid1 = 0; pid2 = 0;}

      编辑测试过了。代码如下

      #include <stdio.h>
      #include <unistd.h>
      
      int main()
      {
          pid_t pid1, pid2;
          pid1 = fork();
          pid2 = fork();
          printf("PID %d: pid1=%d, pid2=%d\n",getpid() ,pid1, pid2);
          exit(0);
      }
      

      输出:

      PID 30805:pid1=30806,pid2=30807
      PID 30806:pid1=0,pid2=30808
      PID 30807: pid1=30806, pid2=0
      PID 30808: pid1=0, pid2=0

      【讨论】:

      • 您忘记了第一个父项中第二个分叉的影响。
      • 我不认为我这样做了...... 4片叶子中的每一片都有其上方的PID变量。顶部(最右边)的叶子有 [child1 pid]、[child2 pid] 等等。我添加了一个表格来澄清
      • 是的,我意识到孩子也 fork()ed。 @Martin York:感谢您的格式...我认为您的副本已过时-我添加了一个表格-但该格式更清晰。
      【解决方案3】:

      在第二个 fork() 之后,pid1 & pid2 的值是多少?

      这取决于您所谈论的过程。这里有四个进程(包括原来的),它们之间的关系如下:

      A (original process)
      ` - B (created by first fork in original process)
      |   ` - C (created by second fork in B)
      ` - D (created by second fork in original process)
      

      所以在 A 中,pid1 &gt; 0pid2 &gt; 0,因为它在每个 fork 上创建了新进程。

      在B中,pid1 == 0pid2 &gt; 0,因为它是由第一个fork创建的,在第二个fork中又创建了一个新进程。

      在 C 中,pid1 == 0pid2 == 0,因为它从其父 (B) 继承 pid1 的值,并且是由第二个分叉创建的。

      在 D 中,pid1 &gt; 0pid2 == 0,因为它从其父级 (A) 继承了 pid1 的值,并且是由第二个分叉创建的。

      当然,请记住,这些只是初始条件。每个进程都有自己的值副本,因此即使进程从其父进程继承了某个变量的初始值,它仍然可以在 fork 之后更改,而不会影响父进程的副本。

      【讨论】:

        【解决方案4】:

        阅读手册页:http://linux.die.net/man/2/fork

        因此,

        pid1 在第一个 fork 中创建的第一个进程的子进程中将为 0,而在主进程及其第二个子进程中则为其他值。 pid2 在第一个进程的孙子进程和主进程的第二个分叉中创建的子进程中将为 0。其他地方的其他东西。

                                                    /-[parent]pid1=?, pid2=?
              /-[parent]pid1=?, pid2=uninit -> fork()
        fork()                                      \-[child2 of parent]pid1=?, pid2=0
             \
              \                                               /-[child1 of parent]pid1=0,pid2=?
               \[child1 of parent] pid1=0, pid2=uninit -> fork()
                                                              \-[child of child] pid1=0, pid2=0
        

        【讨论】:

          【解决方案5】:

          Fork 以现有状态获取进程并对其进行克隆,因此现在您有两个相同的副本。在原始进程中,fork 然后返回新克隆进程的 PID。在新的克隆中,fork 返回 0。

          Parent process:
          pid1 = PID of child 1
          pid2 = PID of child 3
          
          Child 1
          pid1 = 0
          pid2 = PID of child 2
          
          Child 2
          pid1 = 0
          pid2 = 0
          
          Child 3
          pid1 = PID of child 1
          pid2 = 0
          

          【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2021-05-30
          • 2016-10-05
          • 1970-01-01
          • 2018-06-15
          • 1970-01-01
          • 1970-01-01
          • 2023-01-19
          相关资源
          最近更新 更多