假设有一个PID = 1
的进程,它运行以下代码:
int a = fork();
int b = fork();
printf(“a: %d, b: %d\n”, a, b);
让我们进一步假设新的PID
将逐个给出,因此第二个PID
将是2
,然后是3
等。
可能的输出是:
a:2, b:3
a:2, b:0
a:0, b:4
a:0, b:0
我在尝试理解上述代码的输出方面遇到了一些麻烦,尤其是为什么a:0, b:4
和a:2, b:3
。
答案 0 :(得分:12)
你知道吗
返回值是子节点中的零和父节点中子节点的进程标识号,或者出错时为-1。
所以,让我们一步一步地看到这里发生了什么。
调用fork()
后,会创建一个ID为n
的新子项,然后在子0
和父n
中返回。
因此,我们假设我们的进程为pid 1
,当第一个fork()
被调用时,它会创建一个带有pid 2
的进程,然后返回一个值。 a
在流程0
(孩子)中的值为2
,在流程2
(父级)中的值为1
。
然后,每个进程都会调用fork()
并将返回值分配给父进程中的b
。在孩子中,b
的值为0
。
无论如何,我认为这种架构将简化理解:
主要开始:
|
|
int a = fork(); // It creates a new process, and the old one continues going
|
|-------------------------|
a = 2; /* Parent */ a = 0; // Child
| |
| |
int b = fork(); int b = fork(); // Each one create a new process
| |
| |-----------------------------|
| /* Child -> Parent */ // Child -> Child
| a = 0; b = 4; a = 0; b = 0
|
|
|
|
|-----------------------------|
/* Parent -> Parent */ // Parent -> Child
a = 2; b = 3; a = 2, b = 0;
答案 1 :(得分:4)
在第一次分叉之前:
PID 1 (father)
a = (not in scope yet)
b = (not in scope yet)
第一次分叉后:
PID 1 (father)
a = 2
b = (not in scope yet)
PID 2 (child of 1)
a = 0
b = (not in scope yet)
第二次分叉后:
PID 1 (father)
a = 2
b = 3
PID 2 (child of 1)
a = 0
b = 4
PID 3 (child of 1)
a = 2
b = 0
PID 4 (child of 2)
a = 0
b = 0
答案 2 :(得分:4)
我甚至都没有回答你的问题。它更多的是关于显示常用的模式。如果注释中只有正确的代码格式,则可能是注释。
fork()
的基本构造是:
if (int PID = fork() == 0 ) {
//it's a child process
} else {
//it's a parent process
}
使用简单的
int PID1 = fork();
int PID2 = fork();
非常危险,因为您几乎肯定会收到Race condition
。
答案 3 :(得分:1)
在fork
之后,你可以在父亲(fork
返回孩子的PID)或孩子(fork
返回0
)中
首次调用fork
后,您将拥有2个进程:父亲(示例中为a = 2
)和子女(a = 0
)。
两者都会分叉,父亲(a = 2
)会给一个孩子(b = 0
)和一个新父亲(b = 3
)。孩子(a = 0
)会给一个新的孩子(b = 0
),并将其作为父亲(b = 4
)。
您可能的输出是:
a:2, b:3 -> father and father
a:2, b:0 -> father and child
a:0, b:4 -> child and father
a:0, b:0 -> child and child
答案 4 :(得分:0)
Original process:
forks child A, and child B
prints `a:2, b:3`
child A process:
forks child BB
prints `a:0, b:4`
child BB proess:
forks nothing
prints `a:0, b:0`
child B process:
forks nothing
prints `a:2, b:0`
由于您未使用任何wait
或waitpid
,因此可以按任何顺序显示。