【Linux下进程机制】从一道面试题谈linux下fork的运行机制
今天一位朋友去一个不错的外企面试linux开发职位,面试官出了一个如下的题目:
给出如下C程序,在linux下使用gcc编译:
#include "stdio.h" #include "sys/types.h" #include "unistd.h" int main() { pid_t pid1; pid_t pid2; pid1 = fork(); pid2 = fork(); printf("pid1:%d, pid2:%d\n", pid1, pid2); }
要求如下:
已知从这个程序执行到这个程序的所有进程结束这个时间段内,没有其它新进程执行。
1、请说出执行这个程序后,将一共运行几个进程。
2、如果其中一个进程的输出结果是“pid1:1001, pid2:1002”,写出其他进程的输出结果(不考虑进程执行顺序)。
明显这道题的目的是考察linux下fork的执行机制。下面我们通过分析这个题目,谈谈linux下fork的运行机制。
预备知识
这里先列出一些必要的预备知识,对linux下进程机制比较熟悉的朋友可以略过。
1、进程可以看做程序的一次执行过程。在linux下,每个进程有唯一的PID标识进程。PID是一个从1到32768的正整数,其中1一般是特殊进程init,其它进程从2开始依次编号。当用完32768后,从2重新开始。
2、linux中有一个叫进程表的结构用来存储当前正在运行的进程。可以使用“ps aux”命令查看所有正在运行的进程。
3、进程在linux中呈树状结构,init为根节点,其它进程均有父进程,某进程的父进程就是启动这个进程的进程,这个进程叫做父进程的子进程。
4、fork的作用是复制一个与当前进程一样的进程。新进程的所有数据(变量、环境变量、程序计数器等)数值都和原进程一致,但是是一个全新的进程,并作为原进程的子进程。
解题的关键
有了上面的预备知识,我们再来看看解题的关键。我认为,解题的关键就是要认识到fork将程序切成两段。看下图:
上图表示一个含有fork的程序,而fork语句可以看成将程序切为A、B两个部分。然后整个程序会如下运行:
step1、设由shell直接执行程序,生成了进程P。P执行完Part. A的所有代码。
step2、当执行到pid = fork();时,P启动一个进程Q,Q是P的子进程,和P是同一个程序的进程。Q继承P的所有变量、环境变量、程序计数器的当前值。
step3、在P进程中,fork()将Q的PID返回给变量pid,并继续执行Part. B的代码。
step4、在进程Q中,将0赋给pid,并继续执行Part. B的代码。
这里有三个点非常关键:
1、P执行了所有程序,而Q只执行了Part. B,即fork()后面的程序。(这是因为Q继承了P的PC-程序计数器)
2、Q继承了fork()语句执行时当前的环境,而不是程序的初始环境。
3、P中fork()语句启动子进程Q,并将Q的PID返回,而Q中的fork()语句不启动新进程,仅将0返回。
解题
下面利用上文阐述的知识进行解题。这里我把两个问题放在一起进行分析。
1、从shell中执行此程序,启动了一个进程,我们设这个进程为P0,设其PID为XXX(解题过程不需知道其PID)。
2、当执行到pid1 = fork();时,P0启动一个子进程P1,由题目知P1的PID为1001。我们暂且不管P1。
3、P0中的fork返回1001给pid1,继续执行到pid2 = fork();,此时启动另一个新进程,设为P2,由题目知P2的PID为1002。同样暂且不管P2。
4、P0中的第二个fork返回1002给pid2,继续执行完后续程序,结束。所以,P0的结果为“pid1:1001, pid2:1002”。
5、再看P2,P2生成时,P0中pid1=1001,所以P2中pid1继承P0的1001,而作为子进程pid2=0。P2从第二个fork后开始执行,结束后输出“pid1:1001, pid2:0”。
6、接着看P1,P1中第一条fork返回0给pid1,然后接着执行后面的语句。而后面接着的语句是pid2 = fork();执行到这里,P1又产生了一个新进程,设为P3。先不管P3。
7、P1中第二条fork将P3的PID返回给pid2,由预备知识知P3的PID为1003,所以P1的pid2=1003。P1继续执行后续程序,结束,输出“pid1:0, pid2:1003”。
8、P3作为P1的子进程,继承P1中pid1=0,并且第二条fork将0返回给pid2,所以P3最后输出“pid1:0, pid2:0”。
9、至此,整个执行过程完毕。
所得答案:
1、一共执行了四个进程。(P0, P1, P2, P3)
2、另外几个进程的输出分别为:
pid1:1001, pid2:0
pid1:0, pid2:1003
pid1:0, pid2:0
进一步可以给出一个以P0为根的进程树:
总结
应该说这不是一道特别难或特别刁钻的题目,但是由于fork函数运行机制的复杂性,造就了当两个fork并排时,问题就变得很复杂。解这个题的关键,一是要对linux下进程的机制有一定认识,二是抓住上文提到的几个关于fork的关键点。朋友说,这个题给的时间是5分钟,应该说时间还算充裕,但是在面试的场合下,还是很考验一个人对进程、fork的掌握程度和现场推理能力。
希望本文能帮助朋友们对fork的执行机制有一个明晰的认识。
【Linux下进程机制】从一道面试题谈linux下fork的运行机制的更多相关文章
- 从一道面试题谈linux下fork的运行机制
http://www.cnblogs.com/leoo2sk/archive/2009/12/11/talk-about-fork-in-linux.html
- (转)linux下fork的运行机制
转载http://www.cnblogs.com/leoo2sk/archive/2009/12/11/talk-about-fork-in-linux.html 给出如下C程序,在linux下使用g ...
- 小学生之浅谈Struts2与struts1的运行机制
Struts1工作原理图: 1.初始化:struts框架的总控制器ActionServlet是一个Servlet,它在web.xml中配置成自动启动的Servlet,在启动时总控制器会读取配置文件(s ...
- 再谈内存管理与ARC运行机制(一)
内存管理 内存在Objective-C开发中是一种相对稀缺的资源,拿Iphone4为例,它的内存只有512mb,所以妥善的处理好所创造,所使用的每个对象与变量都将成为一个问题.在ARC出现以前,同大部 ...
- ASP.NET整体运行机制+asp.net请求管道+页面生命周期+MVC整体运行机制原理图
在网上找的,个人感觉很好的
- C#与Linux守护进程
用C#编写Linux守护进程 如果要在Red Hat Enterprise Linux上将.NET Core进程作为后台进程运行,则可以创建自定义systemd单元.今天我将为.NET Core编 ...
- linux管理进程的链表
linux2.6.11的内核中,为了方便管理linux的进程,主要建了5种linux链表.每个链表节点之间的互联有两种方式,一种是hash节点之间的互联,通过hlist_node的数据结构来实现:另一 ...
- JavaWeb三大组件——过滤器的运行机制理解
过滤器Filter 文章前言:本文侧重实用和理解. 一.过滤器的概念. lFilter也称之为过滤器,它是Servlet技术中最实用的技术,WEB开发人员通过Filter技术,对web服务器管理的所有 ...
- JSP基本用法(一)运行机制和语法
一.概述 JSP是一种建立在Servlet规范功能上的动态网页技术,在网页文件中嵌入Java代码和JSP标记用于产生动态内容. 本文简单介绍JSP的运行机制和JSP的语法. 二.JSP的运行机制 JS ...
随机推荐
- unity3d进行脚本资源打包加载
原地址:http://www.cnblogs.com/hisiqi/p/3204752.html 本文记录如何通过unity3d进行脚本资源打包加载 1.创建TestDll.cs文件 public c ...
- Tooltip jqueryui
(文章是从我的个人主页上粘贴过来的,大家也可以访问我的主页 www.iwangzheng.com) http://jqueryui.com/tooltip/ <meta charset=&quo ...
- 学号160809212姓名田京诚C语言程序设计实验2选择结构程序设计
编写一个C程序,输入3个数,并按由大到小的顺序输出. 1 #include <stdio.h> void main(){ int a,b,c,t; printf("请输入三个整数 ...
- maven常见问题
maven常见错误: 一..在Eclipse导入已存在工作空间的项目,出现 情况1: Scanning errors (1):1 Could not read pom.xml 就是pom.xml出现了 ...
- asp.net 网站 或者web Api 发布
asp.net 发布iis时可能遇到的内部服务错误常见的有两种: 1.如下图,500.19 Internal Server Error(内部服务错误) 这种错误可能是由于本机的注册表中的asp.net ...
- dell idrac8 部署操作系统的方法
1,打开虚拟控制台 2,“虚拟介质”->“连接虚拟介质”->“映射虚拟介质到CD”->(选择要安装的镜像文件)->“Map device” 3, “next boot”-> ...
- 【SpringMVC】SpringMVC系列4之@RequestParam 映射请求参数值
4.@RequestParam 映射请求参数值 4.1.概述 Spring MVC 通过分析处理方法的签名,将 HTTP 请求信息绑定到处理方法的相应人参中.Spring MVC 对控制器处理 ...
- Android 和iOS 中关于View 的一点知识
View的概念和方法十分重要,这里将对Android 和iOS中出现的,关于视图的一些知识点进行总结,预计文章会比较长,要许多时间慢慢补充. 先转载一部分资料,感谢原作者! 原链接为:http://b ...
- sqlserver的执行计划
一:执行计划生成过程 说到执行计划,首先要知道的是执行计划大概生成的过程,这样就可以做到就心中有数了,下面我画下简图: 1. 分析过程 这三个比较容易理解,首先我们要保证sql的语法不能错误,sele ...
- 原创centos7安装hadoop2.7(转载请注明出处)
启用ip vi /etc/sysconfig/network-scripts/ifcfg-ONBOOT=yes 编辑DNS /etc/resolv.conf nameserver 114.114.11 ...