一、原理解释:
fork()调用可以创建一个和当前进程一样的新进程,调用该函数后,会返回两个结果,分别为父进程ID和子进程ID,如果无法创建,返回-1.子进程会继承父进程的整个地址空间,其中包括了进程上下文,堆栈地址,内存信息进程控制块(PCB)等,以下是父子进程之间差别。
父子进程之间的区别:
- 父进程设置了锁,子进程不继承
- 进程ID不同
- 子进程的未决告警被清除
- 子进程的未决信号集设置为空集
二、案例解释
以下案例主要实现功能:
创建父进程A,子进程B;在父进程A中继续创建父进程A',子进程C,然后每个进程做加法运算,打印结果,查看每个进程运行情况,并观察父进程变化。
#include<stdio.h>
#include<unistd.h>
#include<stdlib.h>
#include<time.h>
#include<errno.h>
int main(void)
{
static int a=0;
static int father_b=0;
pid_t fpid=fork();//创建父进程和子进程
if(fpid>0){//如果返回的当前子进程ID大于0,说明该进程为父进程,
//以下操作在当前父进程中(进程ID 3946,创建子进程(输出结果中的进程ID:3948)
printf("process id is %d \n",getpid());//打印当前进程号
printf("------------------start------------\n");
fork();//在当前父进程中创建当前进程和子进程,实际创建成功后,
//进程数有4个,查看结果详细了解。
for(int i=0;i<5;i++){
father_b=father_b+1;
printf("father_b is %d ,process id is %d,father id is %d\n",father_b,getpid(),getppid());
//getpid为获取当前进程号,getppid为获取父进程号
sleep(1);//每计算一次,休眠1秒,以此查看每个进程并发执行情况
}
sleep(10);//父进程处理完后,休眠10秒,以此观察子进程的情况;
}
else if(fpid==0) {//该进程的子进程号为0,说明是子进程,当前子进程号为3947。
for(int i=0;i<8;i++){
a=a+1;
printf("\n");
printf("son is a=%d,process id is %d,father id is %d\n",a,getpid(),getppid());
输出结果:
$ ./testMoreFork
process id is 3946
------------------start------------
father_b is 1 ,process id is 3946,father id is 539
son is a=1,process id is 3947,father id is 3946
father_b is 1 ,process id is 3948,father id is 3946
father_b is 2 ,process id is 3948,father id is 3946
father_b is 2 ,process id is 3946,father id is 539
father_b is 3 ,process id is 3948,father id is 3946
father_b is 3 ,process id is 3946,father id is 539
son is a=2,process id is 3947,father id is 3946
father_b is 4 ,process id is 3948,father id is 3946
father_b is 4 ,process id is 3946,father id is 539
father_b is 5 ,process id is 3948,father id is 3946
father_b is 5 ,process id is 3946,father id is 539
son is a=3,process id is 3947,father id is 3946
son is a=4,process id is 3947,father id is 3946
son is a=5,process id is 3947,father id is 3946
son is a=6,process id is 3947,father id is 3946
zhang:~ zhangwenhui$
son is a=7,process id is 3947,father id is 1
son is a=8,process id is 3947,father id is 1
------------------end--------------
查看以上运行结果,可以看到进程之间关系如下:
1、初始化进程ID:539,该初始化进程创建父进程3946和子进程3947,在3946父进程中,又创建了子进程3948,具体序列如下:
539-》3946-》3947
-》3948
2、查看运行结果,发现几个进程在控制台上交错打印结果,并发做累加计算。
3、查看黄色部分,发现父进程ID号从3946变成了 1,为啥会出现该问题呢?
解释说明:父进程3946在运行完之后(从粉色部分可以看出)就退出了,那子进程3947就变成孤儿进程,为了做好进程管理,系统安排init进程收养了该进程,以便实现后续资源回收。