Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/70.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 无法理解fork()输出_C_Fork_Pid - Fatal编程技术网

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

因此,让我们假设我们的进程为pid
1
,当调用第一个
fork()
时,它将创建一个具有pid
2
的进程,然后返回一个值<代码>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
remaind
2
?因为3是1的孩子,因此在第二次调用
fork
之前,它是1的完整克隆,包括
a
的值。