一个进程,包括代码、数据和分配给进程的资源。fork()函数通过系统调用创建一个与原来进程几乎完全相同的进程,也就是两个进程可以做完全相同的事,但如果初始参数或者传入的变量不同,两个进程也可以做不同的事。
一个进程调用fork()函数
系统先给新的进程分配资源,例如存储数据和代码的空间。
然后把原来的进程的所有值都复制到新的新进程中,只有少数值与原来的进程的值不同。
相当于克隆了一个自己。
参考下面一个例子:
#include <stdio.h>
#include<unistd.h>
int main(void ){
pid_t fpid ;//fpid表示fork函数到返回值
int count=0;
fpid=fork();
if(fpid<0) printf("错误,结束\n");
if(fpid==0) printf("son %4d %4d %4d \n",getppid(),getpid(),fpid);
else printf("pa %4d %4d %4d \n",getppid(),getpid(),fpid);
return 0;
}
fpid=fork(); 这里通过fork函数创建了一个子进程,并且把返回值存在fpid中。
下一步,操作系统会选择一个进程运行。因为两个进程执行没有固定的先后顺序,哪个进程先执行要看系统的进程调度策略。
所以我们根据fpid的返回值进行判断
如果fpid=0 说明现在处于子进程中,这时fpid返回的值为0。
如果fpid>0 说明现在处于父进程中,这时fpid为儿子的编号。
那为什么不是从#include处开始复制代码的?
因为fork是把进程当前的情况拷贝一份,执行fork时,进程已经执行完了int count=0;fork只拷贝下一个要执行的代码到新的进程。
对上面执行的一个解释:
程序运行到fpid=fork();的时候,进程当前的情况拷贝一份,创建出另外一个和当前进程几乎一模一样的子进程,然后继续选择一个进程运行,在这里很明显选择了pa,然后再son。最后结束运行。
二、fork进阶知识
首先我们来看这一段代码:
#include <stdio.h>
#include<unistd.h>
int main(void ){
pid_t fpid ;//fpid表示fork函数到返回值
int count=0;
printf("son/pa ppid pid fpid count\n");
for(;count<2;count++){
fpid=fork();
if(fpid<0) printf("错误,结束\n",count);
if(fpid==0) printf("son %4d %4d %4d %d\n",getppid(),getpid(),fpid,count);
else printf("pa %4d %4d %4d %d\n",getppid(),getpid(),fpid,count);
}
return 0;
}
第一行:2868创建子进程2869(i=0)
第二行:2868创建子进程2870(i=1)
第三行:子进程2869运行(i=0)
第四行:2869创建子进程2871(i=1)
第五行:进程2871运行(i=1)
第六行:进程2870运行(i=1)
为什么前面有的进程的父进程为1?因为原来的父进程已经运行结束了。
结论:
2*(1+2+4+……+2的N-1次方)
参考链接:(111条消息) 【linux】linux中fork()详解(实例讲解)|fork的运行机制_fork()_bandaoyu的博客-CSDN博客