Chinaunix首页 | 论坛 | 博客
  • 博客访问: 233508
  • 博文数量: 69
  • 博客积分: 1415
  • 博客等级: 上尉
  • 技术积分: 570
  • 用 户 组: 普通用户
  • 注册时间: 2009-03-13 16:57
文章分类

全部博文(69)

文章存档

2011年(1)

2010年(5)

2009年(63)

我的朋友

分类:

2010-08-28 19:21:03



linux进程创建提供了几个常用的函数,像fork,vfork,clone等,在用的时候总是感觉难以运用自如,特别是vfork的使用,在写下自己的一点心得体会!
与fork相比,vfork的工作机制更清晰一些。vfork用于创建一个新进程,而该进程的目的是exec一个新程序,与fork不 同,vfork并不将父进程的地址空间完全复制到子进程中,因为子进程会立即调用exec(或exit),于是也就不会存放该地址空间。在子进程调用 exec或exit之前,它在父进程的空间中运行,这种优化工作方式在某些unix的页式虚拟存储器实现中提高了效率。比写时复制的部分复制更快一些。
对于fork而言,它完全复制父进程的数据空间、堆和栈,父子进程共享正文段。由于fork之后经常跟随exec,现在流行一种写是复制 (Copy-On-Write)技术,这些区域由父子进程共享,而且内核将他们的访问权限改变为只读,如果父子进程中的任意一个试图修改这些区域,则内核 只为修改区域的那块内存制作一个副本,通常是虚拟存储系统中的“一页”。
vfork和fork的另一个区别是:vfork保证子进程先运行,在他调用exec或exit之后父进程才可能被调度。
所以下面的代码 父子进程的输出结果是不一样的,子进程修改属于自己的区域或是采用写时复制复制出要改变的数据,所以子进程输出的是修改后的,父进程不变!
#include
#include
#include
int global = 100;
int main( int argc, char *argv[])
{
 int var=1;
 pid_t pid;
 if((pid=fork())<0)
 {
  printf("Fork error!\n");
 }
 else if( pid == 0)
 {
  printf("In child\n");
  global++;
  var++;
  _exit(0);
 }
 printf("Pid is %d\n",getpid());
 printf("the values of global and var are %d,%d\n",global,var);
}
倘若把fork改为vfork,则子进程的输出结果是自加之后的值,父进程的输出结果是未定义的,还有可能会报出段错误!因为父进程要等待子进程调用exec或是exit之后才能调度。
修改如下:
#include
#include
#include
int global = 100;
int main( int argc, char *argv[])
{
 int var=1;
 pid_t pid;
 if((pid=vfork())<0)
 {
  printf("VFork error!\n");
 }
 else if( pid == 0)
 {
  printf("In child\n");
  global++;
  var++;
  _exit(0);
 }
 else
 {
  sleep(2);
 }
 printf("Pid is %d\n",getpid());
 printf("the values of global and var are %d,%d\n",global,var);
exit(0);
}
执行完毕,子进程对父进程的数据进行了修改!
阅读(766) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~