Understand Fork

Understand Fork

本文关键字:Fork Understand      更新时间:2023-10-16

我从里贾纳大学的CS网站上找到了这个代码。http://www2.cs.uregina.ca/~hamilton/courses/330/notes/unix/fork/fork.html

#include <unistd.h>
#include <iostream>
using namespace std;
int main()
{
    cout << "0. I am process " << getpid() << endl;
    (void) fork();
    cout << "1. I am process " << getpid() << endl;
    (void) fork();
    cout << "2. I am process " << getpid() << endl;
}

程序的输出如下:

$ ./a.exe
0. I am process 2196
1. I am process 2196
1. I am process 6560
2. I am process 6560
2. I am process 4472
2. I am process 2196
2. I am process 2288

我想确保我正确理解这个程序。创建图看起来像这样吗:

        2196
     /        
   2196       6560
             /    
      2288    6560  4472

创建的第一个进程是2196(父进程),创建的进程是6560(子进程)。由于再次调用了fork,因此创建了6560(现在是父级)4472。同时,2196(来自第一个分叉)仍在运行,并创建了2288(子)。因此,总共进行了4个过程(2个父母和2个孩子)。这是正确的吗?

您的理解几乎是正确的。但是,您不能确定44722288的父级,它们可能是21966560

要找到答案,您可以将代码更改为以下代码:

#include <unistd.h>
#include <iostream>
using namespace std;
int main()
{
    cout << "0. I am process " << getpid() << " child of " << getppid() << endl;
    (void) fork();
    cout << "1. I am process " << getpid() <<  " child of " << getppid() <<endl;
    (void) fork();
    cout << "2. I am process " << getpid() <<  " child of " << getppid() <<endl;
}

注意

通常,使用n fork()调用,您最终会得到2 ^ (n)唯一的进程。

例如,这里的n = 2,因此您可以获得2 ^(2) = 4的唯一进程。

是的,这基本上是正确的,因为您没有在分叉后使用wait。目前还不确定哪个过程确切地创造了哪个过程,但关于孩子数量等的主要理论是正确的。你的扩展图是这样的(忽略确切的过程编号,它们可能会改变,但图的形式):

1. stage:           2196
                  /      
                 /        
2. stage:       2196       6560
               /         /   
3. stage:    2196 2288   6560  4472

可以通过打印当前pid(getpid)和父pid(getppid)来计算出确切的进程标识符。

严格地说,如果引入线程等,这甚至会变得更加复杂。

您总是可以通过打印getppid(获取parend进程id)来查看哪个进程与哪个进程相关。

总之,您从一个过程开始,即2196。这将自己一分为二,2196+6560,每一个过程分为两个过程,形成四个过程。从打印的内容中无法判断哪个是哪个的父进程(添加父进程pid将使您能够看到这一点),但最终显然有四个进程。

不完全是这样,您的树包含两次第一个初始进程,但它应该只有一次,您有三次第一个子进程,但也应该只有一个。最初的过程将有两个孩子,第一个孩子将有一个孩子。

然而,我们不可能知道确切的树,因为我们无法判断哪个父级创建了pid 4472和pid 2288。您还需要打印出父pid(getppid),以知道哪个子属于哪个父。

所以树可以看起来像这个

2196/\6560 2288/4472

或者它可能看起来像这个

2196/\6560 4472/2288