vfork函数
vfork和fork函数的调用方法(calling sequence)和返回值是一样。但是两个函数的语义不同。
当目地是使用exec建立一个新的子进程时,可以使用vfork。vfork和fork建立新进程是一样的,只是不复制父进程的地址空间到子进程中,就像子进程不引用那些地址空间一样,子进程只是在vfork后立即调用exec。反之,在子进程调用exec或exit之前,它都是在父进程的地址空间中代替复制地址空间。这种优化在一些unix系统的页式虚拟内存上有效率的增加。
vfork和fork的另一个不同是,vfork可以保证子进程先运行,直到子进程调用exec或exit。当子进程调用其它程序时父进程才继续运行。但这容易引起死锁,因为如果子进程的运行是依赖于父进程的运行状态的话,就会发生死锁。
vfork和fork的最大不同是vfork的子进程生活在父进程的地址空间中,但不复制父进程的地址空间到自己的进程中来,这样子进程的子进程就无法得到祖先进程的地址空间。如:
A>B>C
A是父进程,B是子进程,C是B的子进程。B可以得到A的地址空间,但C不能得到A的地址空间。(这是我的猜测:P)
注意:在使用vfork的时候,子进程要注意用exit退出。因为vfork的子进程生活在父进程的地址空间中,所以子进程不用exit退出的话,会使父进程退出“两次”。例如:
#include <stdio.h>
#include <unistd.h>static void f1(void), f2(void);
int main(void)
{
f1();
f2();
_exit(0);
}static void f1(void)
{
int i=0;
pid_t pid;
if ((pid = vfork()) < 0)
printf(“vfork error”);
if (pid == 0) //如果不在这里把子进程退出的话,f1()在子进程退出一次,之后在父进程退出时会出错,因为已经在子进程退出过了。
_exit(0);
}static void f2(void)
{char buf[10];
int i;for (i = 0; i < sizeof(buf); i++)
buf[i] = 0;
}