Chinaunix首页 | 论坛 | 博客
  • 博客访问: 420989
  • 博文数量: 93
  • 博客积分: 6000
  • 博客等级: 准将
  • 技术积分: 1052
  • 用 户 组: 普通用户
  • 注册时间: 2008-03-19 11:01
文章分类

全部博文(93)

文章存档

2011年(1)

2009年(26)

2008年(66)

我的朋友

分类: LINUX

2008-03-25 20:42:17

   今天学Solaris的进程模型,突然看到了其中关于fork()与vfork()两个函数的程序,通过这个程序,加深了对创建进程的认识。程序如下:
#include
#include
#include
#include
globa=6;
int main(void)
{
 var=88;
 pid_t result;
 result = fork();
//result = vfork();
 if(result == -1)
 {
  perror("fork");
  exit;
 }
 else if(result == 0)
 {
  globa++;
  var++;
  printf("The return value is %d\n In child process!!\n My PID is %d\n",result,getpid());
 }
 else
 {
  printf("The return value is %d\n In father process!!\n My PID is %d\n",result,getpid());
 }
 printf("PID=%d,globa=%d,var=%d",getpid(),globa,var);
}
程序运行结果如下:
(fork()运行结果)
The return value is 0
 In child process!!
 My PID is 3736
PID=3736,globa=7,var=89
The return value is 3736
 In father process!!
 My PID is 3735
PID=3735,globa=6,var=88
 
(vfork()运行结果)
The return value is 0
 In child process!!
 My PID is 3736
PID=3736,globa=7,var=89
The return value is 3736
 In father process!!
 My PID is 3735
PID=3735,globa=7,var=89
 
分析:首先分析fork与vfork函数的运行机制,拿fork为例,fork()并不是进程切换,而是复制一个当前进程。当使用pid=fork()时,其实是创建了两个进程,这两个进程有着相同的内容,例如变量的值,空间配,特别是正在执行的语句等等都相同,但这些内容却在两个独立的内存空间中。因此当执行上述代码时,便相当于同一段代码在两个进程中执行,所有就出现了两个结果,一个是子进程的信息,一个是父进程的信息。再看globa和var这两个变量,由于是两个独立的进程,因此当各自执行代码时,变量也不会互相受到影响,所以在子进程中的globa和var均发生了变化,而在父进程中却没有变化。
     其次分析一下,fork()和vfork()的区别:vfork采用写时拷贝技术(write-on-copy),父进程与子进程享用同一个内存空间,因此,程序中的变量其实也就是父子进程的公共变量,所以,当其中一个进程中的变量值发生改变时,另一个进程中的变量值肯定也跟着发生变化,另外,两个函数的区别还在于vfork用于创建一个新进程,而该新进程的目的是exec一个新进程,vfork和fork一样都创建一个子进程,但是它并不将父进程的地址空间完全复制到子进程中,因为子进程会立即调用exec,于是也就不会存放该地址空间。不过在子进程中调用exec或exit之前,他在父进程的空间中运行。vfork保证子进程先运行,在她调用exec exit之后父进程才可能被调度运行。如果在调用这两个函数之前子进程依赖于父进程的进一步动作,则会导致死锁。 用fork函数创建子进程后,子进程往往要调用一种exec函数以执行另一个程序,当进程调用一种exec函数时,该进程完全由新程序代换,而新程序则从其main函数开始执行,因为调用exec并不创建新进程,所以前后的进程id 并未改变,exec只是用另一个新程序替换了当前进程的正文,数据,堆和栈段。 
阅读(1664) | 评论(0) | 转发(1) |
给主人留下些什么吧!~~