Chinaunix首页 | 论坛 | 博客
  • 博客访问: 124835
  • 博文数量: 20
  • 博客积分: 911
  • 博客等级: 准尉
  • 技术积分: 210
  • 用 户 组: 普通用户
  • 注册时间: 2008-09-03 21:02
文章分类
文章存档

2010年(4)

2009年(3)

2008年(13)

分类: LINUX

2008-10-10 17:14:57

fork()vfork()的使用

昨天的《操作系统》课上,老师让下次上机做关于进程的实验,因为我这几天正好在看Linux的进程方面的内容,所以就把这几天所学的知识总结一下。

操作系统需要一种机制创建新的进程,fork()vfork()就是Linux提供给程序开发人员用于创建进程的函数。

Fork()

使用fork()就要包含两个库;函数的形式是:pid_t fork(void);调用成功时返回两次,如果是在父进程中,返回子进程的进程号,如果在子进程中,返回0;失败时返回值为-1

在调用fork函数后,fork调用点产生与父进程相同的子进程,也就是说,fork函数后的代码是被父进程和子进程分别执行的。

Vfork()

Vfork系统调用函数与fork()调用比较类似,就不再详细介绍了。

Vfork函数用于创建新的进程,父子进程共享虚拟内存空间。在Linux系统中,vfork()的实现类似于fork(),都是用于创建调用进程的子进程。

 

两者的区别:

传统的fork()在创建新的子进程的时候会复制所有父进程所拥有的资源。当然,这一特点有它不尽如人意的地方:使用fork()创建新的进程的目的往往不是为了创建一个和父进程完全一样的进程,很多时候是为了调用exec来执行另一个可执行程序。因此,复制所有父进程的资源是多余的操作。

当使用vfork()系统调用来创建子进程的时候,不会复制父进程的相关资源,父子进程将共享地址空间。子进程对虚拟内存空间的任何修改实际上是在修改父进程虚拟内存空间的内容。在使用vfork()创建子进程后,父进程会被阻塞,直到子进程调用了exec或者_exit()退出。子进程不能使用return返回或调用exit(),但是可以调用_exit()

通过共享父进程的地址空间,vfork()避免了fork()带来的资源复制消耗。

 

举例说明两者区别:

程序p1.cp2.c在子进程中修改了全局变量的取值,在父进程中显示同名变量的取值。

//p1.c

#include

#include

#include

int g_var=0;

int main(void)

{

pid_t pid;

int var=1;

//输出fork()调用前的变量取值

printf(“process id:%ld\n”,(long)getpid());

printf(“before execute the fork system call,g_var=%d var=%d\n”,g_var,var);

//在子进程中改变变量取值,并输出

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

{

perror(“Can’t create a new process”);

return 1;

}

else if(pid==0)

{

g_var++;

var++;

printf(“process id:%ld,g_var=%d var=%d\n”,(long)getpid(),g_var,var);

_exit();

}

//输出父进程中的取值情况

printf(“process id:%ld,g_var=%d var=%d\n”,(long)getpid(),g_var,var);

return 0;

}

 

gcc编译并运行,结果

michenggang@michenggang-desktop:~$  gcc –o p1 p1.c

michenggang@michenggang-desktop:~$ ./p1

process id:24537

before execute the fork system call,g_var=0 var=1

process id:24538,g_var=1 var=2

process id:24537,g_var=0 var=1

可以看到在子进程中改变变量不会影响父进程中变量的取值。

修改上边的程序,将其中使用fork()的语句进行替换,使用vfork(),并将代码保存为p2.c。编译并运行,结果

michenggang@michenggang-desktop:~$ gcc –o p2 p2.c

michenggang@michenggang-desktop:~$ ./p2

process id:24574

before execute the fork system call,g_var=0 var=1

process id:24538,g_var=1 var=2

process id:24537,g_var=1 var=2

可以看到子进程修改变量会导致父进程中对应变量值的改变。

 

 

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