Understand Fork
Understand 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个孩子)。这是正确的吗?
您的理解几乎是正确的。但是,您不能确定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
的唯一进程。
是的,这基本上是正确的,因为您没有在分叉后使用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
- execlp() 在 fork() 之后无法正常工作
- 在 fork() 之后,我在我的程序中不断得到相同的 pid
- 从stdin读取时子进程挂起(fork/dup2竞争条件)
- 为什么if(fork()==0){getpid()}和popen()进程返回相同的进程id
- While循环在fork和execvp调用后没有继续
- fork(),在C中共享内存和指针
- fork/pipes和运行多个程序
- Gdb 未加载要在 fork 使用的源文件
- fork() 无法使用 Cygwin
- PID 不使用 fork() 定义类型
- 为什么我应该使用 fork() 来守护我的进程?
- 修改跨 fork() 的指针中的数据
- C++ fork() 和 execl() 调用 (Linux) 后无法识别命令
- 在 fork() 之后,如何在 for() 循环中继续运行 execve()
- 如何在最后一个子 fork() 下打印带有其名称和 pid 的子进程
- fork()和exec()两个子进程
- 我试图了解 fork() 函数序列是如何工作的?
- 如何使用gmock框架模拟c++单元测试中的fork和execlp系统调用
- 使用 fork 创建子进程时,父 ID 与父 ID 不同
- Understand Fork