C 无法理解fork()输出
让我们假设有一个进程的C 无法理解fork()输出,c,fork,pid,C,Fork,Pid,让我们假设有一个进程的PID=1,它运行以下代码: int a = fork(); int b = fork(); printf(“a: %d, b: %d\n”, a, b); 让我们进一步假设新的PIDs将一个接一个地给出,因此第二个给定的PID将是2,然后是3等等 可能的输出是: a:2, b:3 a:2, b:0 a:0, b:4 a:0, b:0 a:2, b:3 -> father and father a:2, b:0 -> father and child a:
PID=1
,它运行以下代码:
int a = fork();
int b = fork();
printf(“a: %d, b: %d\n”, a, b);
让我们进一步假设新的PID
s将一个接一个地给出,因此第二个给定的PID
将是2
,然后是3
等等
可能的输出是:
a:2, b:3
a:2, b:0
a:0, b:4
a:0, b:0
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
我在试图理解上面代码的输出时遇到了一些困难,尤其是为什么
a:0,b:4
和a:2,b:3
在fork
之后,你可以是父亲(fork
返回孩子的PID)或者是孩子(fork
返回0
)
在第一次调用fork
之后,您将有两个进程:父进程(a=2
,在您的示例中)和子进程(a=0
)
两者都会分叉,父亲(a=2
)会给孩子(b=0
)和新父亲(b=3
)。子项(a=0
)将产生一个新的子项(b=0
),它将是该子项的父亲(b=4
)
您可能的输出是:
a:2, b:3
a:2, b:0
a:0, b:4
a:0, b:0
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
在第一个分叉之前:
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
在第一个分叉之后:
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
第二个fork之后:
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
你知道吗
返回值是子进程中的零和父进程中子进程的进程id号,或者错误时为-1
让我们一步一步来看看这里发生了什么
调用fork()
时,它会创建一个id为n
的新子级,然后返回子级0
和父级n
因此,让我们假设我们的进程为pid1
,当调用第一个fork()
时,它将创建一个具有pid2
的进程,然后返回一个值<代码>a在进程2
中有值0
(子进程),在进程1
中有值2
(父进程)
然后每个进程将调用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;
我甚至不想回答你的问题。它更多的是显示常用的模式。如果注释中有正确的代码格式,它可能是注释
fork()
的基本结构是:
if (int PID = fork() == 0 ) {
//it's a child process
} else {
//it's a parent process
}
使用简单
int PID1 = fork();
int PID2 = fork();
这是非常危险的,因为您几乎可以肯定会收到竞态条件
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
命令,因此这些命令可以按任何顺序显示。谢谢。它可能很简单,但为什么在PID 3
,a=2
?为什么a
remaind2
?因为3是1的孩子,因此在第二次调用fork
之前,它是1的完整克隆,包括a
的值。