惠州网站建设怎么样,网商网官网,中国广告在国外投放案例,网站界面设计描述今天一位朋友去一个不错的外企面试linux开发职位#xff0c;面试官出了一个如下的题目#xff1a;给出如下C程序#xff0c;在linux下使用gcc编译#xff1a;#include stdio.h#include sys/types.h#include unistd.hint main(){pid_t …今天一位朋友去一个不错的外企面试linux开发职位面试官出了一个如下的题目 给出如下C程序在linux下使用gcc编译#include stdio.h#include sys/types.h#include unistd.hint 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将程序切成两段。看下图 上图表示一个含有fork的程序而fork语句可以看成将程序切为A、B两个部分。然后整个程序会如下运行 step1、设由shell直接执行程序生成了进程P。P执行完Part. A的所有代码。 step2、当执行到pid fork();时P启动一个进程QQ是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、再看P2P2生成时P0中pid11001所以P2中pid1继承P0的1001而作为子进程pid20。P2从第二个fork后开始执行结束后输出“pid1:1001, pid2:0”。 6、接着看P1P1中第一条fork返回0给pid1然后接着执行后面的语句。而后面接着的语句是pid2 fork();执行到这里P1又产生了一个新进程设为P3。先不管P3。 7、P1中第二条fork将P3的PID返回给pid2由预备知识知P3的PID为1003所以P1的pid21003。P1继续执行后续程序结束输出“pid1:0, pid2:1003”。 8、P3作为P1的子进程继承P1中pid10并且第二条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为根的进程树验证 下面我们去linux下实际执行这个程序来验证我们的答案。 程序如下图 用gcc编译、执行后结果如下 由于我们不太可能刚巧碰上PID分配到1001的情况所以具体数值可能和答案有所差别。不过将这里的2710看做基数的话结果和我们上面的解答是一致的。总结 应该说这不是一道特别难或特别刁钻的题目但是由于fork函数运行机制的复杂性造就了当两个fork并排时问题就变得很复杂。解这个题的关键一是要对linux下进程的机制有一定认识二是抓住上文提到的几个关于fork的关键点。朋友说这个题给的时间是5分钟应该说时间还算充裕但是在面试的场合下还是很考验一个人对进程、fork的掌握程度和现场推理能力。 希望本文能帮助朋友们对fork的执行机制有一个明晰的认识。更多干货资料点击这里