fork函数二三事 - webdancer's Blog
fork函数二三事
1.fork函数的基本功能
在linux中,只有一个函数可以创建子进程:fork。
#include <sys/types.h> #include <unistd.h> pid_t fork(void);
由fork创建的新进程被称为子进程( child process)。该函数被调用一次,但返回两次。两次返回的区别是子进程的返回值是0,而父进程的返回值则是新子进程的进程I D。将子进程I D返回给父进程的理由是:因为一个进程的子进程可以多于一个,所以没有一个函数使一个进程可以获得其所有子进程的进程I D。fork使子进程得到返回值0的理由是:一个进程只会有一个父进程,所以子进程总是可以调用getppid以获得其父进程的进程ID(进程ID 0总是由交换进程使用,所以一个子进程的进程ID不可能为0 )。
2.CoW(Copy on Write)
CoW是现代操作系统中的一个很重要的策略,在fork中也使用了。看一下下面这个例子。
#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<sys/types.h>
int main(){
int i;
pid_t p0;
if((p0=fork())<0){
perror("error!");
exit(0);
}
else if(p0==0){
i=getpid();
printf("i is %d the i address is %p in the child\n",i,&i);
}
else {
i=getpid();
printf("i is %d the i address is %p in the parent\n",i,&i);
}
return 0;
}
运行的结果:
i is 3132 the i address is 0xbf8147e8 in the parent
i is 3133 the i address is 0xbf8147e8 in the child
为什么会有相同的i地址呢?不是当fork()产生子进程的时候,会copy吗?
因为现代的OS基本采用了COW技术。父子进程共享数据和堆。
3.缓冲问题
在这里http://coolshell.cn/articles/7965.html看到了一个很有趣的问题,代码如下:
#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;
}
问一下:上面到底会输出几个‘-'。答案不是六个,而是八个。原因就是因为父进程的buffer也被子进程继承了。详细的分析可以参照Coolshell的这篇文章http://coolshell.cn/articles/7965.html。
评论 (0)