(1)Fork被调用一次则会返回两次,有三种不同的返回值:
1.在父进程中,fork返回新创建子进程的进程ID
2.在子进程中,fork返回0
3.如果出现错误,fork返回一个负值,出错的原因有:1.当进程数已经达到系统规定的上限,这时,errno的值被设置为EAGAIN 2.系统内存不足时,errno的值被设为
ENOMEM
(2)创建新进程成功后,系统中出现两个基本完全相同的进程,这两个进程执行的先后顺序没有规定,哪个进程先执行要看系统的进程调度策略。
(3)每个进程都有独特的进程标识号PROCESS ID,可以通过getpid(),父进程pid通过getppid()
(4)范例:
#include<unistd.h>
#include<stdio.h>
int main(void){
for(int i=0;i<2;i++){
pid_t fpid=fork();
if(fpid==0){
printf("%d child %4d %4d %4d\n",i,getppid(),getppid(),fpid);
}else{
printf("%d parent%4d %4d %4d\n",i,getppid(),getppid(),fpid);
}
}
return 0;
}
run result:
0 parent2043 32243225
0 child3224 32250
1 parent2043 32243226
1 parent3224 32253227
1 child1 3227 0
1 child1 3226 0
1step->在main进程2043中执行fork之后,系统分成两个进程一个父进程p3224,一个子进程p3225。
code被分成两份:
for(int i=0;i<2;i++){//i=0
pid_t fpid=fork();//fpid=p3225
if(fpid==0){
printf("%d child %4d %4d %4d\n",fpid,getpid(),getppid(),fpid);
}else{
printf("%d parent%4d %4d %4d\n",fpid,getpid(),getppid(),fpid);
}
}
在fork完成之后的父进程p3224中的打印:i=0,getppid()=p2043,getpid()=p3224,fpid=p3225.在fork完成之后的子进程p3225中的打印:i=0,getppid()=p3224,getpid()=p3225,fpid=0.
fork完成之后,code被分成两份,for循环i=1,在父进程p3224中进程又被分成两份p3224,p3226;在父进程p3225中进程也被分成两份p3225,p3227.
假设都是父进程先执行:
在进程P3224,fork完成之后的父进程p3225中的打印:i=1,getppid()=p2043,getpid()=p3224,fpid=p3226
在进程p3225,在fork完成之后的父进程p3226中的打印:i=1,getppid()=p3225,getpid()=p3225,fpid=p3227
子进程执行:
在进程p3224,fork完成之后的子进程p3226中的打印:i=1,getppid()=1,getpid=p3226,fpid=0
在进程p3225,fork完成之后的子进程p3227中的打印:i=1,getppid()=1,getpid=p3227,fpid=0
这里有个知识点,getppid()原本是等于p3224,但是因为父进程在执行完i=1,之后就退出main了,这样p3224,p3225死亡后,p3226,p3227没有了父进程
这在操作系统中是不被允许的,所以p3226,p3227的父进程被置为p1,p1是永远不会死亡的。
这个程序一共产生了三个子进程p3225,p3226,p3227,一共打印6次。