1.介绍(来自百度百科):
UNIX及类UNIX(UNIX-like)系统中的分叉函数。返回值: 若成功调用一次则返回两个值,子进程返回0,父进程返回子进程标记;否则,出错返回-1。
fork函数将运行着的程序分成2个(几乎)完全一样的进程,每个进程都启动一个从代码的同一位置开始执行的线程。这两个进程中的线程继续执行,就像是两个用户同时启动了该应用程序的两个副本。
2.测试代码如下:
// ubuntu
int main(){
pid_t pid[3];
int i;
for(i = 0; i < 3; i++){
pid[i] = fork();
if(pid[i] == 0){
printf("子进程id: %d,父进程id: %d\n",getpid(),getppid());
}else{
printf("当前进程id: %d,子进程id: %d\n",getpid(),pid[i]);
sleep(3);
}
printf("\n");
}
}
3.测试代码运行结果:
当前进程id: 20308,子进程id: 20309
子进程id: 20309,父进程id: 20308
当前进程id: 20309,子进程id: 20310
子进程id: 20310,父进程id: 20309
当前进程id: 20310,子进程id: 20311
子进程id: 20311,父进程id: 20310
当前进程id: 20308,子进程id: 20312
子进程id: 20312,父进程id: 20308
当前进程id: 20309,子进程id: 20313
子进程id: 20313,父进程id: 20309
当前进程id: 20312,子进程id: 20314
子进程id: 20314,父进程id: 20312
当前进程id: 20308,子进程id: 20316
子进程id: 20316,父进程id: 20308
注意:输出为了方便查看我重新拍了一下序,因为fork()不保证进程之间的执行顺序,输出的内容很有可能是错位的,因为进程之间在交替进行,原执行结果如下:
4.程序进程流程如下:
08进程运行for第1次循环,产生子进程09,注意fork()会将进程的状态也一并复制过去,即当前08进程和09进程中,for循环中 i 的值都为1,之后运行if语句并输出不同的结果,08和09进程的第一次for循环结束。
注:父进程中fork()返回 子进程进程号,子进程中fork()返回 0,可以用来区分父/子进程
09进程运行for第2次循环,和上一步一样,09进程fork(),产生10进程,此时09进程的状态也一并复制过去,10进程的for也处于第2次循环,之后09和10进程运行if并结束第2次循环。
注:fork()会优先运行子进程中,这和fork进程时,系统采用写时复制有关,具体可以查看文章底部的参考博客
10进程进行第3次for循环,fork出进程11,此时10进程和11进程中for循环都为第3次,之后将不再循环。
此时09的子进程都执行完毕,09继续运行for第3次循环,fork出进程12。
09进程及其下子进程运行完毕,此时08开始继续运行第2次for循环,fork出13子进程。同理,13进程进行第3次for循环,fork出14子进程。
13进程及其下子进程运行完毕,08进程运行for第3次循环,产生子进程16,然后8和16中for循环结束,输出并结束进程:
流程汇总如下:
颜色代表当前进程状态
参考博客:
https://blog.csdn.net/kwinway/article/details/79633285
https://blog.csdn.net/xy010902100449/article/details/44851453