Chinaunix首页 | 论坛 | 博客
  • 博客访问: 2096253
  • 博文数量: 249
  • 博客积分: 1305
  • 博客等级: 军士长
  • 技术积分: 4733
  • 用 户 组: 普通用户
  • 注册时间: 2011-12-17 10:37
个人简介

不懂的东西还有很多,随着不断的学习,不懂的东西更多,无法消灭更多不懂的东西,那就不断的充实自己吧。 欢迎关注微信公众号:菜鸟的机器学习

文章分类

全部博文(249)

文章存档

2015年(1)

2014年(4)

2013年(208)

2012年(35)

2011年(1)

分类: C/C++

2013-07-24 16:50:16


    创建一个新的进程的方法只有由某个已经存在的进程调用fork或者vfork函数,当然某些进程如init等作为系统启动的一部分而被内核创建的。

    (1)fork函数介绍
  1. #include <unustd.h>
  2. pid_t fork(void);
  3.                     返回值:子进程中返回0,父进程中返回子进程ID,出错返回-1
    子进程是父进程的一个拷贝。具体来说,子进程从父进程那得到数据段、堆和栈,但不是与父进程共享而是单独分配内存。fork函数返回后,子进程和父进程都是从fork函数的下一条语句开始执行的。
    由于子进程与父进程的运行是无关的,父进程可优先于子进程运行,子进程也可以优先于父进程运行,所以下段程序可以有不同的运输结果。
  1. #include <stdio.h>
  2. #include <sys/types.h>
  3. #include <unistd.h>
  4. int globa = 4;
  5. int main (void )
  6. {
  7.         pid_t pid;
  8.         int vari = 5;
  9.         printf ("before fork\n" );
  10.         if ((pid = fork()) < 0)
  11.         {
  12.                 printf ("fork error\n");
  13.                 exit (0);
  14.         }
  15.         else if (pid == 0)
  16.         {
  17.                 globa++ ;
  18.                 vari--;
  19.                 printf("Child changed\n");
  20.         }
  21.         else
  22.         {
  23.                 printf("Parent did not changde\n");
  24.         }
  25.         printf("globa = %d vari = %d\n",globa,vari);
  26.         exit(0);
    运行结果如下所示(可能的一种结果)。

    
    (2)vfork函数介绍
    vfork函数创建新进程的主要目的在于exec函数执行另外的程序。实际上,在没有调用exec或exit之前子进程的运行中是与父进程共享数据段的。在vfork调用中,子进程先运行,父进程挂起,直到子进程调用exec或exit,在这以后,父子进程的执行顺序不再有限制。
  1. #include <stdio.h>
  2. #include <sys/types.h>
  3. #include <unistd.h>
  4. int globa = 4;
  5. int main (void )
  6. {
  7.         pid_t pid;
  8.         int vari = 5;
  9.         printf ("before fork\n" );
  10.         if ((pid = vfork()) < 0)
  11.         {
  12.                 printf ("fork error\n");
  13.                 exit (0);
  14.         }
  15.         else if (pid == 0)
  16.         {
  17.                 globa++ ;
  18.                 vari--;
  19.                 printf("Child changed\n");
  20.                 _exit(0);
  21.         }
  22.         else
  23.         {
  24.                 printf("Parent did not changde\n");
  25.         }
  26.         printf("globa = %d vari = %d\n",globa,vari);
  27.         exit(0);
    运行结果如下所示。

    上面的执行结果与fork不同,执行的结果是固定的。

  
    三个主要不同点:
    (1)fork()后子进程拷贝父进程的数据段、堆和栈;vfork后子进程与父进程共享数据段
    fork()用于创建一个新进程。由fork()创建的子进程是父进程的副本,即子进程获取父进程的数据空间、堆和栈的副本。父子进程之间不共享这些存储空间的部分。
    而vfork()创建的进程并不将父进程的地址空间完全复制到子进程中,因为子进程会立即调用exec(或exit),于是,也就不会存放该地址空间。相反,在子进程调用exec或exit之前,它在父进程的空间中运行。
    (2)vfork()和fork()另一个区别是:fork父子进程的执行次序不确定,vfork保证子进程先运行,在调用exec或exit之前与父进程数据是共享的,在它调用exec或exit之后,父进程才可能被调度运行。
    (3)vfork保证子进程先运行,在它调用exec或exit之后父进程才可能被调度运行。如果在调用者两个函数之前子进程依赖于父进程的进一步动作,则会导致死锁。
    
    相同点:
    两者被调用一次,但是返回两次。两次返回的唯一区别是子进程的返回值是0,而父进程的返回值则是新子进程的进程ID。




    引自:http://linux.chinaunix.net/techdoc/develop/2009/07/16/1124441.shtml、《UNIX环境高级编程》

    










    
阅读(844) | 评论(0) | 转发(1) |
给主人留下些什么吧!~~