- 1、本文档共5页,可阅读全部内容。
- 2、原创力文档(book118)网站文档一经付费(服务费),不意味着购买了该文档的版权,仅供个人/单位学习、研究之用,不得用于商业用途,未经授权,严禁复制、发行、汇编、翻译或者网络传播等,侵权必究。
- 3、本站所有内容均由合作方或网友上传,本站不对文档的完整性、权威性及其观点立场正确性做任何保证或承诺!文档内容仅供研究参考,付费前请自行鉴别。如您付费,意味着您自己接受本站规则且自行承担风险,本站不退款、不进行额外附加服务;查看《如何避免下载的几个坑》。如果您已付费下载过本站文档,您可以点击 这里二次下载。
- 4、如文档侵犯商业秘密、侵犯著作权、侵犯人身权等,请点击“版权申诉”(推荐),也可以打举报电话:400-050-0827(电话支持时间:9:00-18:30)。
查看更多
两道有趣的fork面试题
同学参加了EMC 的笔试回来,说了一个EMC 的一个笔试题目,他没有答上
来,就问我。我感觉很有意思,就拿出来分析一下
int main(int argc,char* argv[])
{
fork();
fork() && fork() || fork();
fork();
}
为了解答这个问题,我们先作一下弊,先用程序验证一下,到此有多少个进
程。
int main(int argc, char* argv[])
{
fork();
fork() && fork() || fork();
fork();
printf("+\n");
}
在代码最后加一个printf语句,看最后有多少行,就说明有多少进程。
答案是总共20个进程,出去main进程,还有19个进程。
我们再来仔细分析一下,为什么是还有19个进程。
第一个fork和最后一个fork肯定是会执行的。主要在中间3个fork上,
可以画一个图进行描述。这里就需要注意&&和||运算符。
A&&B,如果A=0,就没有必要继续执行了;A非0,就需要继续执行&&B。
A||B,如果A非0,就没有必要继续执行了,A=0,就需要继续执行||B。
fork()对于父进程和子进程的返回值是不同的,按照上面的A&&B和A||B的分支
进行画图,可以得出5个分支。
加上前面的fork和最后的fork,所有的进程都会执行,会产生4个分支,总共
4*5=20个分支,也就是20个进程,除去main主进程,就是19个进程了。
前两天有人问了个关于Unix的fork()系统调用的面试题,这个题正好是我
大约十年前找工作时某公司问我的一个题,我觉得比较有趣,写篇文章与大家分
享一下。这个题是这样的:
#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
int main(void)
{
int i;
for(i=0; i<2; i++){
fork();
printf("-");
}
return 0;
}
如果你对fork()的机制比较熟悉的话,这个题并不难,输出应该是6个“-”,但
是,实际上这个程序会很tricky地输出8个“-”。
要讲清这个题,我们首先需要知道fork()系统调用的特性,
• fork()系统调用是Unix下以自身进程创建子进程的系统调用,一次调用,
两次返回,如果返回是0,则是子进程,如果返回值>0,则是父进程(返回
值是子进程的pid),这是众为周知的。
• 还有一个很重要的东西是,在fork()的调用处,整个父进程空间会原模
原样地复制到子进程中,包括指令,变量值,程序调用栈,环境变量,缓冲
区,等等。
所以,上面的那个程序为什么会输入8个“-”,这是因为printf(“-”);语句,我
们知道,Unix下的设备有“块设备”和“字符设备”的概念,所谓块设备,就是以
一块一块的数据存取的设备,字符设备是一次存取一个字符的设备。磁盘、内存、
显示器都是块设备,字符设备如键盘和串口。块设备一般都有缓存,而字符设备
一般都没有缓存。
所以,对于上述程序,printf(“-”);把“-”放到了缓存中,并没有真正的输出(参
fork
fork
看《C语言的迷题》中的第一题),在ffoorrkk的时候,缓存被复制到了子进程空
间,所以,就多了两个,就成了8个,而不是6个。
我们如果修改一下上面的printf的那条语句为:
printf("-\n");
或者是
printf("-");
flush();
就没有问题了,因为程序遇到“\n”或是EOF,或是缓中区满,或是文件描述符
关闭,或是主动flush,就会把数据刷出缓冲区。
我估计有些朋友可能对于fork()还不是很了解,那么我们把上面的程序改成下
面这样:
#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
int main(void)
{
int i;
for(i=0; i<2; i++){
fork();
//注意:下面的p
文档评论(0)