最近学了fork,讨论了几个有意思的问题,对fork理解更深了一些,记录一下
- 1,vfork
#include<stdio.h>
#include<unistd.h>
#include<sys/types.h>
int a=10;
int main()
{
int b=20;
pid_t pid;
pid =vfork();
if(pid==0)
{
b++;
return 0;//exit (0);//用exit和return各执行一次
}
printf("%d %d",a,b);
}
当我们用return ,他会告诉我们段错区。如果是exit就会正常输出,为什么呢?
我们知道vfork之后,子进程完全运行在父进程的地址空间上,子进程对该地址空间中的任意数据的修改同样为父进程所见。所以子进程对b++后父进程的b也就是21了。
但为什么用exit和return会不同呢?这就是return和exit的区别了。
return是函数级别的返回,return会先释放局部变量,并弹栈,再回到上级函数。所以当返回回父进程时,父进程访问变量时发现他们共用的堆栈区没了,被坑了,所以爆出段错误。而exit是直接退出不会释放堆栈区。
推荐一篇博客,讲的很详细:http://blog.csdn.net/quzhilin123/article/details/41675951
- 2,下面代码会输出几个 ‘-’ ?
#include< stdio.h>
#include< unistd.h>
#include< sys/types.h>
int main()
{
int i;
for(i=0;i<2;i++)
{
fork();
printf(" - ");
}
}
答案会是多少呢?我们来看下面的图:
由图我们可以看到,由于子继承了父的所有数据,所以第一次fork后在父和子中i都会变成2,在之后就会变成3,所以不会无线循环下去;
接着就是图中看到是会输出6次;但是如果你真的跑了一遍的话就会发现是8个;
因为子也继承了父的输出缓存,所以子2,和孙1会继承来于各自的父亲的一次‘-’,所以会输出8次;如果我们在输出‘-’之后在加一个‘\n’(会刷新缓存区)就会发现是六个;
- 3, 下面会输出几种结果?
#include<stdio.h>
#include<unistd.h>
#include<sys/types.h>
#include<sys/wait.h>
int main()
{
pid_t pid1;
pid_t pid2;
pid1=fork();
pid2=fork();
printf("pid1=%d pid2=%d \n",pid1,pid2);
}
还是我们来上一张图:
由图分析我们可以看到有四种输出结果,而且我们知道父子进程号是连号,所以如果给我们父进程的输出结果,我们就可以推出其他三个输出结果。
有两点我们要注意,进程不一定谁先谁后:
1,四种情况输出不一定谁先谁后;
2,子2不一定比孙1出生早,所以父进程输出的两个进程号不一定是连号,有可能是差一个,而差的那一个号一定是孙1的进程号,一定在子1那里输出;