关于linux下fork()函数的解析:子进程继续创建子进程,如何停止?
先贴代码:
for(i = 0; i < 4; i++)
{
fork();
printf("a\n");
}
问:一共输出多少个a? 答:30个(2+4+8+16)
先说下思路:父进程创建子进程后,fork函数是让子进程完全拷贝父进程,包括父进程上下文,什么意思呢?就是说父进程的EIP(CPU的下一条指令地址)以及变量等等一律拷贝,也就是说,父进程执行过的代码子进程是不会再执行,子进程下一条该执行的命令与父进程完全一样!!!
解析:
i=0时;fork()后,产生一个子进程,然后父子进程共同printf各1次;共两次;
之后,父子进程都进入i=1:
- 父子进程都会fork,也就是父进程fork了一个新的子进程;i=0的子进程也fork了一个子进程,共4个进程,每个进程都继续往下执行,也就是printf一次;共4次
以此类推:也就是2+4+8+16=30次。具体看下图:
fork会让子进程拷贝一切父进程的信息,包括这里面的变量i的值,所以子进程不会一直循环的fork下去,在i=2时,子进程(称为p2吧)fork出p3,然后p2继续执行printf,fork后创建的p3子进程的执行位置也和p2一样为printf,同时该创建的p3子进程自然下一次循环是从i=3开始,当i=3完成之后,i变成4,所有由总父进程创建出来的子进程都同时结束。
第二题
请问下面的程序一共输出多少个”-”?
1 2 3 4 5 6 7 8 9 |
|
printf是一个行缓冲函数,先写到缓冲区,满足条件后才将缓冲区刷新到对应文件中,刷新缓冲区的条件如下:
1)缓冲区填满;
2)写入的字符中有‘\n’、'\r';
3)调用fflush手动刷新缓冲区;
4)调用scanf要从缓冲区读取数据时,也会将缓冲区内的数据刷新。
另外,当执行printf的进程或线程结束的时候,也会主动调用flush来刷新缓冲区。
本题中printf没有'\n',是因为进程执行结束,才去刷新缓冲区,在屏幕上显示字符,这是理解本题的关键。
当i=1时,parent进程中printf的缓冲区内容为"--",第一个'-'为i=0时printf的输出,只是没有'\n'而囤积到这一次。child2进程中printf缓冲区的第一个'-'则是因为子进程会复制父进程的缓冲区,因此复制了parent的buf。
需要注意的是i=0时的缓冲区之所以不打印,是因为这两个缓冲区跟i=1时的缓冲区是共用的一个,其中parent和child1缓冲区都到了i=1了,也就是本程序只有4个缓冲区,最后4个缓冲区都被刷新打印出来了,如图所示。
程序结束即所有进程都结束后,会自动刷新缓冲区,此时会一下子把parent,child2,child1和child1_2的缓冲区输出到显示屏幕上,输出的顺序可能会随机。因此最后共输出8个'-'。
更多推荐
所有评论(0)