Fork函数浅谈
一、写作缘由
不知道为啥感觉一年的CSAPP课程学习就要结束了–自信点,不是感觉,是已经结束了。回顾自己的一年学习,感慨颇多。CSAPP号称计算机界的“圣经”,依小生所看,名不虚传,书中知识浩繁,如果能够全部学通,对计算机的理解肯定能够更上一层楼。但小生才能有限,能够过关已是侥幸,故选取书中部分内容附上自己浅薄的见解。
二、fork函数简介
一个进程,包括代码、数据和分配给进程的资源。fork( )函数通过系统调用创建一个与原来进程几乎完全相同的进程,也就是两个进程可以做完全相同的事,但如果初始参数或者传入的变量不同,两个进程也可以做不同的事。
一个进程调用fork( )函数后,系统先给新的进程分配资源,例如存储数据和代码的空间。然后把原来的进程的所有值都复制到新的新进程中,只有少数值与原来的进程的值不同。相当于克隆了一个自己。
它的特点是调用一次返回两次。
fork( )返回两个值
1.返回一个大于0的值给父进程
2.返回0给子进程
3.返回其他值说明fork失败了
我们将A 进程, 也就是调用 fork 的进程称之为父进程, 而新的进程(B 进程)称之为子进程。注意!注意! fork 调用生成的新进程与其父进程谁先执行不一定!
3.fork函数实例
我们先来看看一串代码:
这段代码看上去简简单单,但实际上却暗藏玄机,没有任何fork知识的人很容易就会得出错误的运行结果。那么最后跑出的结果到底是什么样呢?不卖关子,请看下图。
有人可能会对这个运行结果产生一种错觉,就是程序中if语句的两条分支if(pid == 0)和else if(pid > 0)都得到了执行。其实完全不是这么回事,出现这种运行结果的原因是因为,在main()函数调用fork了,创建了一个新的进程,这个进程称为原来进程的子进程。子进程与原来的进程并发执行,谁先谁后没有规律,由操作系统调度决定。 这也就是我们上面所说的,父进程和子进程谁先执行完全无法确定!!
再贴上几张简单fork函数运行图供大家参考:
四、fork面试题精选
既然fork函数如此重要,那么在各大企业招聘测试中见到它也不足为奇。前不久老师在课堂上留下了一道fork面试题,在教室苦苦不能得解,回寝后经过多方努力,最终寻得思路并解出答案,特与大家分享。
问题:该程序共产生了多少个新的子进程?
这道题初见之时,大部分人跟我一样应该都是一脸懵逼,这么多fork到底该如何进行判断,但其实我们仔细捋一捋,还是能发现些许踪迹。
首先,第一个和最后一个fork函数一定会执行。每个fork函数最终产生两个进程,这两个fork就产生:2*2=4个进程,那么,最重要的,是对中间三个组合fork的判断。这里,我们需要着重注意&&和||运算符。
对于A&&B,如果A=0,那么结果为0,无需继续执行;如果A≠0,就需要继续执行,不能直接进行判断。
对于A||B,如果A≠0,那么结果已出,无需继续执行;如果A=0,就需要继续执行,而不能直接进行判断。
那么,我们可以得到下面的分支图:
从该图我们可以清晰的看到,中间三个fork共产生5个分支,那么结合剩余两个fork,一共是:4*5=20个进程,除去main,还剩19个。答案就是19个。
五、个人体会
fork函数在下理解得不深,也借鉴了诸多网上大神的文章内容,加上自己浅薄的认识凑成了这篇博客,我在学习的过程中深感知识浩如烟海,唯有努力才能不断精进。与君共勉。