5进程创建FORK
Posted 捕获一只小肚皮
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了5进程创建FORK相关的知识,希望对你有一定的参考价值。
文章目录
1. fork函数初识
fork函数的作用从已存在的进程中创建一个新的进程,而新进程被称为子进程,原进程称为父进程,我们先看一下当执行fork后会发生什么.
- 分配新的内存块和内核数据结构给子进程
- 将父进程部分数据结构内容拷贝至子进程
- 添加子进程到系统进程列表当中
- fork返回,开始调度器调度
也就是说 当一个进程调用fork之后,就有两个二进制代码相同的进程,而且它们都从fork以后
开始运行到相同的地方,即每个进程都将可以开始它们自己的旅程,如下程序:
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
int main()
pid_t pid;
printf("before,pid=%d,ppid=%d\\n",getpid(),getppid());
pid = fork(); //创建子进程
printf("after,pid=%d,ppid=%d\\n",getpid(),getppid());
return 0;
运行结果为
[MakeBigMoney@VM-12-5-centos ~]$ ./test
before,pid=1390,ppid=29550
after,pid=1391,ppid=1390
after,pid=1390,ppid=29550
可以看到进程1390执行了before
和after
,进程1391也执行了after
,但是1391却没有执行before
,这是为什么呢?
用下图便可解释上面程序的原因:
所以,fork之前父进程独立执行,fork之后,父子两个执行流分别执行。注意,fork之后,谁先执行完全由调度器 决定。
2. fork函数返回值
fork函数有两个返回值
- 给子进程返回0
- 给父进程返回子进程的PID
那它为什么有两个返回值呢,在了解这个概念之前,我们先说一下写时拷贝.
一种写的时候才分配内存空间的拖延策略
说白了就是如果拷贝方对于被拷贝方的数据暂时只有读的需求时,变不开空间,直接用指针指向被拷贝方的空间,当需要写的时候才为其分配一块新的空间,关系如下:
而fork创建子进程时候,便是以父进程为模板,把代码和数据写时拷贝给子进程,根据这个原理,我们在按照这个思路进行理解下面的程序:
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
int main()
pid_t my_pid;
printf("before,pid=%d,ppid=%d\\n",getpid(),getppid());
my_pid = fork(); //创建子进程
printf("after,pid=%d,ppid=%d\\n",getpid(),getppid());
return 0;
一开始父进程执行到了fork位置并创建子进程,然后系统给子进程进行写时拷贝,子进程便拥有了一份和上面一模一样的代码.
fork调用结束,父子进程便可以开始自己的独立旅行,于是父进程代码的my_pid
被赋值,同理!!!,子进程的my_pid
这时候也需要被赋值,于是
系统便重新开辟一块空间给子进程,既然拥有了两个不同的my_pid
,自然就有两个值了
(创建子进程过程如上图)
对于fork可以返回两个值的说法的理解,不如说是两个同名的变量各自接收了一份进程的数据而表现出来fork返回了两个值.
而写时拷贝从另一方面来说,也就保证了进程之间的独立性(因为需要写入的数据都各自私有了,互不影响)
以上是关于5进程创建FORK的主要内容,如果未能解决你的问题,请参考以下文章