如果我们看一下这个例子
#include <stdio.h>
#include <unistd.h>
void main(){
int pi_d ;
int pid ;
pi_d = fork();
if(pi_d == 0){
printf("Child Process B:\npid :%d\nppid:%d\n",getpid(),getppid());
}
if(pi_d > 0){
pid = fork();
if(pid > 0){
printf("\nParent Process:\npid:%d\nppid :%d\n",getpid(),getppid());
}
else if(pid == 0){
printf("Child Process A:\npid :%d\nppid:%d\n",getpid(),getppid());
}
}
}
对我来说,这看起来会无限期地创建进程,因为当我们分叉一个进程时,会创建父进程的副本。这样程序代码就被克隆了。
这意味着每个新进程都运行相同的代码;因此,它调用pi_d = fork()
,等等。
我在这里缺少什么?
答案1
引用自POSIX 分叉定义(粗体强调我的):
返回值
成功完成后,fork() 将向子进程返回 0,并向父进程返回子进程的进程 ID。
fork()
两个进程都应从该函数继续执行。否则,应返回-1给父进程,不会创建子进程,并errno
应设置以指示错误。
OP 写道:
这意味着,对于每个新进程,它都会运行相同的代码
成功完成fork()
并返回后父母和孩子立即恢复fork()
:第一个不会再次执行fork()
,然后第一个或第二个将不会再次执行,fork()
因为此代码中没有循环允许这种情况发生。
假设没有发生错误(没有检查):
- 父分叉
- 如果是子显示器的话
Child Process B
。 - 否则,如果是父级,则再次分叉
- 如果它(再次)是父级,则显示
Parent Process
- 如果是父母的第二个孩子,则显示
Child Process A
- 如果它(再次)是父级,则显示
- 如果是子显示器的话
由于无法保证子级或父级中的哪一个会按照精确的执行顺序击败另一个,因此 3 个输出可以按任何顺序发生或混合发生(但在给定的特定操作系统上,一个显示顺序应该比其他显示顺序更频繁地发生,并且Child Process B
具有领先优势可能会首先显示)。