Chinaunix首页 | 论坛 | 博客
  • 博客访问: 383513
  • 博文数量: 96
  • 博客积分: 647
  • 博客等级: 上士
  • 技术积分: 490
  • 用 户 组: 普通用户
  • 注册时间: 2012-09-29 22:15
文章分类
文章存档

2015年(1)

2014年(10)

2013年(26)

2012年(59)

我的朋友

分类:

2012-10-18 11:24:52

返回值:子进程返回0,父进程返回子进程的PID

对于fork():子进程和父进程继续执行fork之后的代码,子进程获得父进程数据空间、堆、栈的副本,即父子进程并不共享这些存储空间。父子进程只共享代码段。但是,由于fork之后经常跟随exec,所以现在很多的实现并不执行父进程数据空间、堆、栈的完全复制,而是采用写是复制。这些存储空间由父子进程共享,而且内核将它们的访问权限改为只读,如果父子进程中任何一个试图修改这些区域,则内核只为修改区域的那块内存制作一个副本,通常是虚拟存储器系统中的整数倍。记住:父子进程的数据是不相互影响的。

fork函数主要用在两个方面:

1.      一个父进程希望父子自己,是父子进程同时执行不同的代码段。这在网络服务请求中是常见的,父进程等待客户端的服务请求。当这种请求到达时,父进程调用fork,是子进程处理此请求。父进程则继续等待下一个服务请求。

2.      一个进程要执行一个不同的程序。这对shell是常见的情况。在这种情况下,子进程从fork返回后立即调用exec

对于vfork:保证子进程先运行,在它调用execexit之后父进程才可能被调度运行。而且子进程在调用execexit之前是在父进程内存空间运行的。故子进程对数据的改变对父进程是有影响的。

代码:

#include
#include
#include
int glob = 0;
int main(void)
{
 int val = 8;
 pid_t pid;
 if((pid=fork())<0)
  printf("fork error!\n");
 else if(pid==0) //child
 {
  glob++;
  val++;
 }
 else   //parent
 {
  sleep(2);//wait child process
 }
 printf("pid=%d,glob=%d,val=%d\n",getpid(),glob,val);
 exit(0);
}
$./a.out

pid=3472,glob=1,val=9  //子进程输出
pid=3471,glob=0,val=8  //父进程输出

代码:

#include
#include
#include
int glob = 0;
int main(void)
{
 int val = 8;
 pid_t pid;
 if((pid=vfork())<0)
  printf("vfork error!\n");
 else if(pid==0)
 {
  glob++;
  val++;
  exit(0);
 }
 printf("pid=%d,glob=%d,val=%d\n",getpid(),glob,val);
 exit(0);
}

$./a.out
pid=3489,glob=1,val=9

 

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