理解福克

时间:2014-04-26 08:44:32

标签: c++ unix posix fork

我在里贾纳的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个孩子)。这是对的吗?

4 个答案:

答案 0 :(得分: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个唯一流程。

答案 1 :(得分:1)

是的,这大多是正确的,因为你不要在货叉后使用等待。不确定哪个过程确切地创建了哪个过程,但关于孩子数量等的主要理论是正确的。您的扩展图形将是这样的(忽略确切的流程编号,它们可能会更改,但图形的形式):

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

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

严格来说,这可能会随着引入的线程等而变得更加复杂......

答案 2 :(得分:0)

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

然而,由于我们无法分辨哪个父亲创建了pid 4472和pid 2288,因此无法知道确切的树。您还需要打印出父pid(getppid)以了解哪个孩子属于哪个父节点。

因此树可以看起来像这样

          2196
         /    \
     6560      2288
    /
4472

它可能看起来像这样

          2196
         /    \
     6560      4472
    /
2288

答案 3 :(得分:0)

您可以通过打印getppid(获取parend进程ID)始终查看哪个进程与哪个进程相关。

总而言之,你从一个进程开始,2196。这将自己分成两个,2196 + 6560,这些进程分为两个进程,分为四个进程。从你打印的内容中可以看出哪个是父元素是不可能的(添加父pid将使你能够看到它),但最后有四个过程。