【lesson10】fork创建进程的现象解答

文章目录

  • fork现象
  • fork问题

fork现象

我们先来看一段代码。
【lesson10】fork创建进程的现象解答_第1张图片
大家觉得这段代码的printf会打印几次?
结果:
【lesson10】fork创建进程的现象解答_第2张图片
我们可以清楚的看到,第二个printf打印了2次。
我们再来看一段不可思议的代码:
【lesson10】fork创建进程的现象解答_第3张图片
运行结果:
【lesson10】fork创建进程的现象解答_第4张图片
我们可以看到这res竟然有两个值。
从上面我们可以得出结论,fork之后变成了两个进程一个是父进程,一个是子进程。
代码证明:
【lesson10】fork创建进程的现象解答_第5张图片

运行结果:
【lesson10】fork创建进程的现象解答_第6张图片
我们可以看到确实fork之后变成了两个进程。

由此我们可以的出结论:fork之后的代码是父子共享的,所以才会出现上面printf会被打印两次的现象。

我们创建子进程出来就是为了执行不同的代码逻辑,如果代码是共享的我们该如何执行不同的代码逻辑呢?
用以下方法解决:
之前我们学过fork在子进程和父进程中的返回值是不同的
父进程:返回子进程pid
子进程:返回0
创建子进程失败:返回-1

接下来就是解决上面问题的方法:
用分支语句解决。
【lesson10】fork创建进程的现象解答_第7张图片
运行结果:
【lesson10】fork创建进程的现象解答_第8张图片
我们可以看到确实解决了上面的问题。
我们让他们一直循环,看两个进程会不会同时进行
【lesson10】fork创建进程的现象解答_第9张图片
运行结果:
【lesson10】fork创建进程的现象解答_第10张图片
我们在用监测指令,查看两个进程:
【lesson10】fork创建进程的现象解答_第11张图片
我们可以看到Linux中确实存在2个这样的进程,上面是父进程,下面是子进程。
上面说明了:fork之后有两个不同的执行流,各自ret在父子进程中是不一样的。

fork问题

问题一为什么一份C语言代码,其中同一个变量会有不同的值?
下篇博客讲解
问题二为什么给子进程返回的是0,给父进程返回的是子进程的pid
首先我们会理解一个事情:
父进程和子进程的比例一定是一比多的,我们可以理解为一个父亲可以有多个儿子,但是一个儿子一定只有一个父亲。
父进程 : 子进程 = 1 : n
其次举个例子
比如张三有四个孩子子,为了区分他们,分别给孩子们取了名字,小明,小花,小华和小美。有一天小明的老师把张三叫到学校,说小明这次考试不好等等。张三回到家会叫小名你给我过来,还是会叫孩子你给我过来,肯定是叫名字因为有四个孩子如果叫孩子你给我过来歧义太大。
最后推广:
所以上面的例子推广到fork中,就明白为什么fork给父进程返回的是子进程的pid,是为了更好的区分他们。
问题三:为什么fork会有两个返回值?
首先我们要理解一个问题:
创建进程的时候,OS要做什么?
本质就是系统多了一个进程,所以OS要新建一个PCB(task_struc)来管理进程。
【lesson10】fork创建进程的现象解答_第12张图片
子进程PCB(task_struct)结构体的内部属性,要以父进程的PCB结构体为模板创建。
例子:比如你和你父母的DNA一定是相似度很高的。
其次我们要理解:
当fork已经准备return了,fork的核心代码执行完了吗?
我们都知道进程是用PCB结构体管理的,而PCB结构体是存放在链表中的,是以链表的形式管理起来的
【lesson10】fork创建进程的现象解答_第13张图片
那么CPU要调度进程是直接从链表中调度进程吗?
不是的,在Linux中还存在一种运行队列,当进程要被调度是先要被加载到运行队列中。
【lesson10】fork创建进程的现象解答_第14张图片
当进程加载到运行队列中执行完就会被干掉。
【lesson10】fork创建进程的现象解答_第15张图片

所以操作系统和CPU运行某个进程,本质从PCB结构体形成的队列中挑选一个PCB结构体,来执行它的代码和数据,进程调度变成了在PCB结构体的队列中选择一个进程的过程。
只要想到进程优先想到对应的PCB结构体。
【lesson10】fork创建进程的现象解答_第16张图片
而当fork准备return的时候,核心代码数据其实早已经跑完了。
当我们到return的时候其实,父进程和子进程早就已经进入到运行队列中
【lesson10】fork创建进程的现象解答_第17张图片
所以当运行到return时父进程和子进程分别会执行自己return语句,所以就会有两个返回值。
问题四:fork()有两个返回值,意味着会被保存两次吗?
下次博客揭晓。
问题五:父子进程被创建出来了,哪一个进程先被运行完呢?
这个并不一定,因为一个进程并不一定会一直被CPU调度,可能CPU运行个10毫秒就继续运行另一个进程
所以谁先被运行或者先运行完,由操作系统的调度器决定,不由人为决定。

你可能感兴趣的:(linux,linux,运维,服务器)