当我尝试以下程序时,我正在阅读有关fork()的内容。我无法理解以下命令的输出,但我可以弄清楚如果我删除第二个fork()调用它会做什么。请解释以下程序的流程。
#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <error.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
using namespace std;
int main(int argc, char const *argv[])
{
pid_t pid;
int returnvalue;
pid = fork();
pid = fork();
if (!pid) cout<< "In the child"<<endl;
else cout<< "In parent"<<endl;
cout<< (&returnvalue)<<endl;
switch(pid)
{
case -1:
perror("fork");
return 0;
case 0:
cout<< "Child Process with pid: " <<getpid()<<endl;
cout<< "Parent's pid is: "<<getppid()<<endl;
cout<< "Exiting"<<endl;
returnvalue=2;
return returnvalue;
default:
cout<< "Parent process with pid: "<<getpid()<<endl;
cout<< "Child's pid: "<<pid<<endl;
cout<< "Waiting for child to exit"<<endl;
wait(&returnvalue);
cout<< "Child's exit status: "<<WEXITSTATUS(returnvalue)<<endl;
cout<< "Exiting!"<<endl;
}
return 0;
}
为什么打印“父母”和“孩子”两次? 另外,我读到每个子进程都有自己的变量副本。不应该将“returnvalue”的地址打印出来吗? 输出:
In parent
0x7fff2d536428
Parent process with pid: 5487
Child's pid: 5489
Waiting for child to exit
In the child
0x7fff2d536428
Child Process with pid: 5489
Parent's pid is: 5487
Exiting
Child's exit status: 2
Exiting!
In parent
0x7fff2d536428
Parent process with pid: 5488
Child's pid: 5490
Waiting for child to exit
In the child
0x7fff2d536428
Child Process with pid: 5490
Parent's pid is: 5488
Exiting
Child's exit status: 2
Exiting!
答案 0 :(得分:3)
你有2次调用fork()将导致4个进程。
1st fork in P1 --> new process P2
2nd fork in P1 --> new process P3
2nd fork in P2 --> new process P4
为了解释起见,pid将根据第二个fork()之后的结果而有所不同,我只是说P1是父亲并且仍然是父亲,P2是P1的子女,但是是父亲P4,所以它的pid不为零,P3和P4都有pid等于0.所有4个进程都将进入switch语句,并带有一个pid,将它们分类为父或子,所以因为2有pid = 0并且2有pid!= 0,2将被报告为父母,2将被报告为孩子。
P1 pid != 0 (classify parent)
P2 pid != 0 (classify parent)
P3 pid == 0 (classify child)
P4 pid == 0 (classify child)
确实在P2创建P2之前创建了P1,然后在P4之前创建了P3,但是当它们进入switch语句并且打印出来时,它们的消息由调度程序控制。考虑创建一个过程需要花费大量时间(更多只是打印东西)的可能性。因此P1创建P2然后转身创建P3同时P2忙于创建P4。当P2仍然卡住创建P4时,P3会被创建并打印内容。