专注于嵌入式和图像处理
分类: LINUX
2012-02-23 20:37:52
返回值:子进程返回0,父进程返回子进程的PID号
对于fork():子进程和父进程继续执行fork之后的代码,子进程获得父进程数据空间、堆、栈的副本,即父子进程并不共享这些存储空间。父子进程只共享代码段。但是,由于fork之后经常跟随exec,所以现在很多的实现并不执行父进程数据空间、堆、栈的完全复制,而是采用写是复制。这些存储空间由父子进程共享,而且内核将它们的访问权限改为只读,如果父子进程中任何一个试图修改这些区域,则内核只为修改区域的那块内存制作一个副本,通常是虚拟存储器系统中”页”的整数倍。记住:父子进程的数据是不相互影响的。
fork函数主要用在两个方面:
1. 一个父进程希望父子自己,是父子进程同时执行不同的代码段。这在网络服务请求中是常见的,父进程等待客户端的服务请求。当这种请求到达时,父进程调用fork,是子进程处理此请求。父进程则继续等待下一个服务请求。
2. 一个进程要执行一个不同的程序。这对shell是常见的情况。在这种情况下,子进程从fork返回后立即调用exec。
对于vfork:保证子进程先运行,在它调用exec或exit之后父进程才可能被调度运行。而且子进程在调用exec或exit之前是在父进程内存空间运行的。故子进程对数据的改变对父进程是有影响的。
代码:
#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