Chinaunix首页 | 论坛 | 博客
  • 博客访问: 2422966
  • 博文数量: 298
  • 博客积分: 7876
  • 博客等级: 准将
  • 技术积分: 5500
  • 用 户 组: 普通用户
  • 注册时间: 2011-02-23 13:39
文章存档

2013年(2)

2012年(142)

2011年(154)

分类: LINUX

2011-04-04 21:45:48

进程控制fork函数vfork函数

1.1   函数原型:

    头文件:

    pid_t getpid(void);     //返回调用进程的进程ID

    pid_t getppid(void);    //返回进程的父进程ID

    uid_t getuid(void);     //返回调用进程的实际用户ID

    uid_t geteuid(void);   //返回调用进程的有效用户ID

    gid_t getgid(void);     //返回调用进程的实际组ID

    gid_t getegid(void);   //返回调用进程的有效组ID

1.2 fork函数

1. 函数原型:

    pid fork(void);

    头文件:

    返回值:子进程中返回0,父进程中返回子进程ID,出错返回-1

    函数功能:创建一个新进程。

2.示例:

   ************************ 8-1 ****************************

   //使用fork函数创建子进程

  #include "apue.h"

 

int glob = 6;

char buf[] = "a write to stdout\n";

 

int

main(void)

{

    int var;

    pid_t pid;

    var = 88;

    if(write(STDOUT_FILENO, buf, sizeof(buf)-1) != (sizeof(buf)-1))

    printf("write error\n");

    printf("before fork\n");

    fflush(NULL);//注意

    if((pid = fork()) < 0)

    {

       printf("fork error\n");

    }

    else if(pid == 0)

    {

       printf("son :\n");

       glob++;

       var++;

    }

    else

    {

       printf("parent :\n");

       sleep(2);

    }

 

    printf("pid =  %d, var = %d, glob = %d\n", getpid(), var, glob);

    return 0;

}

如果输出到终端设备时是行缓冲的,输出了printf("before fork\n");后数据还在缓冲区里面,在终端下面只能看见一次,而如果重定向到文件时,则变成了全缓冲的,父进程创建子进程时,其缓冲区也复制给了子进程在调用exit之后会刷新缓冲区,所以出现了两个before fork,如果在创建子进程之前刷新缓冲区fflush(NULL),就不会出现这种状况了。

*******************************************************

例程2

#include "apue.h"

 

int glob;

 

int

main(void)

{

    int var;

    pid_t pid;

    printf("before fork \n");

    if((pid =  fork()) < 0)

    {

       printf("fork error");

    }

    else if(pid == 0)

    {

       var = 1;

       glob = 2;

       printf("son : var = %d, glob = %d\n", var, glob);

    }

    else

    {

       var = 3;

       glob = 4;

       printf("parent : var = %d, glob = %d\n", var, glob);

    }

    printf("test \n");

    return 0;

}

 

结果:

before fork

son : var = 1, glob = 2

test

parent : var = 3, glob = 4

test

从结果可以看出子进程是不影响父进程变量的值的,并且父子进程都要执行以后的程序段,这就可能形成竞争,以后会提到解决的方法。

 

1.3 vfork函数

1.  vfork函数用于创建一个新进程,而该新进程的目的是exec一个新程序。

2. vfork函数与fork函数的区别:

   都一个样创建子进程,但是vfork并不将父进程的地址空间完全复制到子进程中,相反,在子进程调用execexit之前,它在父进程

   空间运行。还有,vfork保证子进程运行,在它调用execexit之后父进程才能被调度运行。

例程3

#include "apue.h"

 

int glob = 6;

char buf[] = "a write to stdout\n";

 

int

main(void)

{

    int var;

    pid_t pid;

    var = 88;

    if(write(STDOUT_FILENO, buf, sizeof(buf)-1) != (sizeof(buf)-1))

    printf("write error\n");

    printf("before vfork\n");

    if((pid = vfork()) < 0)

    {

       printf("vfork error\n");

    }

    else if(pid == 0)

    {

       glob++;

       var++;

       _exit(0);

    }

    else

    {

       sleep(2);

    }

 

    printf("pid =  %d, var = %d, glob = %d\n", getpid(), var, glob);

    return 0;

}

 

结果:

a write to stdout

before vfork

pid =  3755, var = 89, glob = 7

从这里可以看出来,在子进程调用execexit之前,它在父进程里面,所以该边了父进程变量的值。

 

 

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