我在里贾纳的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个孩子)。这是对的吗?
答案 0 :(得分:2)
您的理解几乎正确。但是,您无法确定4472
和2288
的父级,可以是2196
或6560
。
要找到答案,您可以将代码更改为以下内容:
#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将使你能够看到它),但最后有四个过程。