fork和vfork两个都是子进程创建函数,这里总结两点常用区别(还有些区别比较杂,不想提~):
1.执行顺序:fork子进程与父进程都要运行(顺序、进度随缘,内核说了算),而vfork一定是子进程先运行,父进程后运行;
2.虚拟内存:fork子进程拷贝父进程内存空间,vfork子进程共享父进程内存空间;
这里注意:使用带缓存的输入输出函数时,fork的子进程会拷贝父进程的缓存,而vfork的子进程会共享父进程的缓存,具体有什么影响后面分析;
简单介绍下两个函数
fork()和vfork()函数:函数调用一次返回两次,对子进程(0)、对父进程(>0、子进程id)各返回一次
fork调用以后就有两个进程了,后续的代码由两个进程各自执行一遍;
第一个执行顺序的区别很好理解,vfork子进程执行完后续代码后,父子进程才开始运行,不在赘述;
第二个虚拟内存的区别,带缓冲文件操作函数的简单代码,一个用fork,一个用vfork:
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
int main()
{
/*带缓存功能函数操作文件*/
FILE *fp=fopen("aaa.txt","w");
fprintf(fp,"pid%d,",getpid()); //父进程写入
fork(); //创建子进程
//vfork();
fprintf(fp,"pid%d,",getpid()); //父、子进程都要写入
fclose(fp);
exit(0);
}
fork对应的aaa.txt写入结果:pid3553,pid3553,pid3553,pid3554,
vfork对应的aaa.txt写入结果:pid3560,pid3561
分析{
这里有不得不说exit除了退出外另一功能——刷新缓存。
fork:也就是说,父进程退出时将两次自己的pid写入文件,而fork创建子进程会拷贝父进程的缓存空间(一个父pid),在子进程运行到exit退出的时候,将先拷贝的父进程pid和后写入的自己pid(都在缓存空间)一起写入文件,一共有四个pid。
vfork:父进程将自己pid写入缓存,vfork子进程共享了父进程的缓存,子进程再往缓存中写入自己的pid,子进程运行退出时写入了父和自己的pid到文件;到父进程运行,发现缓存里面已经没东西了,那就只写自己的pid,这个时候,发现在内存空间,打开的文件被儿子关上了,只能写个寂寞,所以vfork里只有两个pid。
}
附上带缓冲函数文件操作的fork改进版本
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
int main()
{
/*带缓存功能函数操作文件*/
FILE *fp=fopen("aaa.txt","w");
fprintf(fp,"pid%d,",getpid()); //父进程写入
fflush(fp); //刷新缓冲区
fork(); //创建子进程
fprintf(fp,"pid%d,",getpid()); //父、子进程都要写入
fclose(fp);
exit(0);
}
fork对应的aaa.txt写入结果:pid3553,pid3553,pid3554,
可控且达到预期!!
第二个虚拟内存相关,不带缓冲文件操作函数的简单代码,一个用fork,一个用vfork:
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
int main()
{
/*不带缓存功能函数操作文件*/
int fp=open("aaa.txt",O_WRONLY|O_CREAT);
char *s="hello!";
ssize_t size = strlen(s)*sizeof(char);
write(fp,s,size); //父进程写入
fork()
//vfork(); //创建子进程
write(fp,s,size); //父、子进程都要写入
close(fp);
exit(0);
}
fork对应的aaa.txt写入结果:hello!hello!hello!
vfork对应的aaa.txt写入结果:hello!hello!hello!
都是三个hello?
分析{
不带缓存就不分析缓存空间了,但为什么vfork时子进程已经close文件了,另一个进程还可以往里面写入?
答案是我也不知道,求大神指点!!!!
}
附带一个例子:
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
int main()
{
/*不带缓存功能函数操作文件*/
int fp=open("aaa.txt",O_WRONLY|O_CREAT);
char *s="hello!";
ssize_t size = strlen(s)*sizeof(char);
write(fp,s,size); //父进程写入
fork()
//vfork(); //创建子进程
write(fp,s,size); //父、子进程都要写入
close(fp);
write(fp,s,size); //父、子进程都要写入
exit(0);
}
fork对应的aaa.txt写入结果:hello!hello!hello!
vfork对应的aaa.txt写入结果:hello!hello!hello!
这个输出结果居然也是三个hello?
这谁想得通,求指点~~~~