fork函数和vfork函数区别总结 及提问求解

 

 

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?

这谁想得通,求指点~~~~
 

 

 

 

 

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值