机制 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:%dn", 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将程序切成两段。看下图:

8a88aa5c0bbf3cd080a0f90ddbd33f17.png

上图表示一个含有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为根的进程树:

92cfcca74c6d48d673eb46cb285fce3c.png

验证

下面我们去linux下实际执行这个程序,来验证我们的答案。

程序如下图:

105d8aa1ddf22d51b894f6cc0d505c39.png

用gcc编译、执行后结果如下:

ef6b1ae13dda86d62b15cb003ea1f810.png

由于我们不太可能刚巧碰上PID分配到1001的情况,所以具体数值可能和答案有所差别。不过将这里的2710看做基数的话,结果和我们上面的解答是一致的。

总结

应该说这不是一道特别难或特别刁钻的题目,但是由于fork函数运行机制的复杂性,造就了当两个fork并排时,问题就变得很复杂。解这个题的关键,一是要对linux下进程的机制有一定认识,二是抓住上文提到的几个关于fork的关键点。朋友说,这个题给的时间是5分钟,应该说时间还算充裕,但是在面试的场合下,还是很考验一个人对进程、fork的掌握程度和现场推理能力。

希望本文能帮助朋友们对fork的执行机制有一个明晰的认识。

更多干货资料点击这里

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/356193.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

教学案例 计算机,宁夏计算机教学案例

宁夏计算机教学案例,答辩老师不仔细看**跟他们发现不了你**中的问题根本是两个概念。宁夏计算机教学案例, 生手指从未使用过计算机系统的学习者。他们不熟悉计算机的操作,缺乏有关计算机系统的知识。他们对计算机会产生一种陌生的感觉。新手指…

您在2016年会做什么? Apache Spark,Kafka,Drill等

让我们玩得开心。 这是新的一年的开始-我们正处于新事物的门槛上-因此让我们期待您在2016年可能会做的事情。现在我知道做出预测的风险,尤其是有记录的预测,但是我很高兴您能在一年后回访,看看我对2016年的预测是如何完成的。 您在2016年会…

话筒好坏测试软件,如何简单地判断麦克风的质量好坏?

如何简单地判断麦克风的质量好坏?麦克风质量好不好,主要看三点:咪芯,线材和外壳。在挑选麦克风时,我们通常都不会一一上手试用,而是通过它自身的规格参数来进行初步地判断,一般来说,…

怎么保证读取最新数据_Kafka怎么保证数据不丢失?

Kafka怎么保证数据不丢失?这个问题要从3个方面来保证数据不丢失:生产者、服务端、消费者。01producer 生产端是如何保证数据不丢失的1.ack的配置策略acks all (或-1)生产者在发送消息之后,需要等待ISR中所有的副本都成功写入消息之后才能够收…

怎么圆角变直角_衣柜设计个圆角有什么用?效果好看又实用,会这样装的都是老木工...

衣柜设计个圆角有什么用?效果好看又实用,会这样装的都是老木工随着生活水平的不断提高,大家对于生活质量也有着越来越高的期望。从生活起居以及房子的装修中,我们可以看出来。因此家里的东西堆积的也更加的多,这对于储…

浙大计算机硕士比本科985,二本出身的985研究生与985本科生,哪个更厉害?网友:差的太多!...

原标题:二本出身的985研究生与985本科生,哪个更厉害?网友:差的太多!概率,还是概率问题。即便2本考研到985是很优秀,但能优秀到让985本科生服气的还是少数。说到底,是因为考研不是绝对…

5调用外部浏览器打开代码_浏览器事件循环

浏览器运行过程中会同时面对多种任务,用户交互事件(鼠标、键盘)、网络请求、页面渲染等。而这些任务不能是无序的,必须有个先来后到,浏览器内部需要一套预定的逻辑来有序处理这些任务,因此浏览器事件循环诞生了,再次强…

JVM上的高并发HTTP客户端

HTTP可能是最流行的应用程序级别协议,并且有许多库在网络I / O之上实现它,这是常规I / O的一种特殊(面向流)情况。 由于所有I / O都有很多共同点1 ,所以让我们开始对其进行一些讨论。 我将集中讨论具有大量并发HTTP请…

win10系统卷影复制服务器,如何使用Windows卷影拷贝服务恢复文件和文件夹

本文介绍了如何使用Windows卷影拷贝服务恢复文件和文件夹,分享给大家,具体如下:什么是卷影拷贝?从Windows XP SP2和Windows Server 2013开始,微软就向Windows操作系统中引入了一项名叫卷影拷贝的服务(Volume Shadow Co…

Nginx下配置Http Basic Auth

nginx basic auth指令 第一条语句: 语法: auth_basic string | off;默认值: auth_basic off;配置段: http, server, location, limit_except 默认表示不开启认证,后面如果跟上字符,这些字符会在弹窗中显示。 第二条语句&#xff…

服务器多核性能排行,服务器内存多核性能

服务器内存多核性能 内容精选换一换本文介绍了弹性云服务器ECS的功能发布和对应的文档动态,新特性将在各个区域(Region)陆续发布,欢迎体验。关于弹性云服务器(ECS)更多历史版本变更内容,请单击“查看PDF”详细了解。超高I/O型弹性云服务器使用…

从去除毛刺的策略看开运算opening_circle和闭运算closing_circle的异同

例一:毛刺在往外凸的面上 策略1:分割出黑色部分,然后通过开运算去掉毛刺,再通过原黑色部分区域减去开运算之后的区域,得到毛刺部分的区域。 1 read_image (Tu, C:/Users/xiahui/Desktop/tu.jpg) 2 binary_threshold (…

买服务器带操作系统,买服务器带操作系统

买服务器带操作系统 内容精选换一换只有运行中的弹性云服务器才允许用户登录。Linux操作系统用户名“root”。忘记密码,请先通过“重置密码”功能设置登录密码。重置密码:选中待重置密码的云耀云服务器,并选择“操作”列下的“ 重置密码”。重…

自定义sql_【PL/SQL 自定义函数】 常用场景

看完这章后你会学习到以下内容:1.练习场景2.面试场景3.工作应用场景总览思维导图:面试部分:1.创建函数,从emp表中查询指定员工编号的职工的工资CREATE OR REPLACE FUNCTION CHECK_SAL(F_EMPNO IN EMP.EMPNO%TYPE) RETURN NUMBER ISV_SAL VARC…

进阶– Java EE 7前端5强

系列继续。 在初步概述和Arjan关于最重要的后端功能的文章之后 ,我现在非常高兴让Ed Burns( edburns )使用他最喜欢的Java EE 7前端功能完成本系列。 感谢Markus Eisele让我有机会在他非常受欢迎的博客上发表帖子。 我和Markus的关系可以追溯…

一杯水怎么测试_一杯水就能鉴别翡翠真假的高招

大家好,小生有礼!鄙人是秋玉蝉珠宝的杨杨,很高兴能在茫茫互联网中相识就是有缘。先简单介绍一下秋玉蝉珠宝,我们是年轻的品牌,我们的理念一直秉承坚持做真翡翠,好翡翠,把握翡翠的精髓&#xff0…

php连接mysql_PHP连接MySQL数据库的三种方式

本篇文章给大家介绍一下PHP连接MySQL数据库的三种方式(mysql、mysqli、pdo),结合实例形式分析了PHP基于mysql、mysqli、pdo三种方式连接MySQL数据库的相关操作技巧与注意事项。有一定的参考价值,有需要的朋友可以参考一下,希望对大家有所帮助…

idea内置junit5_JUnit的内置Hamcrest Core Matcher支持

idea内置junit5在通过JUnit和Hamcrest改善对assertEquals的文章中,我简要讨论了Hamcrest “ 核心 ”匹配器与JUnit的现代版本“结合”在一起的情况。 在那篇文章中,我特别关注了JUnit的assertThat(T,Matcher)静态方法与…

jenkins 发送邮件模板

jenkins 发送邮件模板 <!DOCTYPE html> <html> <head> <meta charset"UTF-8"> <title>${ENV, var"JOB_NAME"}-第${BUILD_NUMBER}次构建日志</title> </head><body leftmargin"8" marginwidth"…

Oracle Spring Clean JavaFX应该吗?

我们确实在Codename One上依赖JavaFX&#xff0c;我们的模拟器需要它。 我们的桌面版本使用它&#xff0c;而我们的设计器工具基于Swing。 我们希望它成功&#xff0c;这对我们的业务至关重要&#xff01; 即使您是Java EE开发人员并且不关心桌面编程&#xff0c;我们也不是一个…