在这里总结关于进程的四道面试题:
第一道
问下面程序打印几个A。
#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
int main()
{
int i = 0;
for(;i<2;++i)
{
fork();
printf("A\n");
}
exit(0);
}
答:一共fork两次,如下:
第一次fork:存在进程1和2,一共打印2个A
第二次fork:存在进程1、2、3、4,一共打印4个A
所以一共会打印6个A。
第二道
在第一道的基础上修改代码如下,问产生几个A。
#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
int main()
{
int i = 0;
for(;i<2;++i)
{
fork();
printf("A");
}
exit(0);
}
第一次fork,存在进程1和2,各打印1个A
第二次fork,存在进程1、2、3、4,这时进程1和2分别产生1个A,进程3和4分别产生2个A,因为prinf没有刷新缓存区,进程3和4将其父进程缓存区的内容拷贝过来,所以一共有2+1+1+2+2=8个A。
第三道
思考下面程序的打印结果。
首先,printf函数是带有缓冲区的,而write函数不带缓冲区,在子进程中将父进程printf函数的缓冲区拷贝过来,因此在子进程的printf函数中存在一个A。这就是为什么有两个A的原因。
接下来还有一个问题,那就是B出现在A之前。这是还是因为printf函数是待缓存区的,只有当缓存区遇到换行符、fflush刷新缓冲区或者缓冲区满了它才会将内容输出到屏幕,而write由于不带缓存区,因此会立即输入到屏幕。
两个AA是因为在程序结束的时候,exit(0)会对IO流进行冲洗,因此AA是在程序结束的时候打印出来的。_exit和_EXIT函数不会对IO流进行冲洗,如果将上述的exit用_exit或者_EXIT替换,那么可以发现AA就不会打印出来。
第四道
问下面代码会产生几个进程。
#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
int main()
{
fork()||fork();
exit(0);
}
我们知道fork会在子进程中返回0(运行成功)。刚开始父进程执行fork,产生一个子进程,fork在父进程中返回子进程pid,父进程不会继续向右执行,而在子进程中fork()返回0,会向右执行,因此子进程又调用fork,产生一个孙子进程。所以程序结束之前,存在父进程、子进程、孙子进程三个进程。程序产生了两个进程。