vfork函数

vfork函数

vfork和fork函数的调用方法(calling sequence)和返回值是一样。但是两个函数的语义不同。

当目地是使用exec建立一个新的子进程时,可以使用vforkvforkfork建立新进程是一样的,只是不复制父进程的地址空间到子进程中,就像子进程不引用那些地址空间一样,子进程只是在vfork后立即调用exec。反之,在子进程调用execexit之前,它都是在父进程的地址空间中代替复制地址空间。这种优化在一些unix系统的页式虚拟内存上有效率的增加。

vforkfork的另一个不同是,vfork可以保证子进程先运行,直到子进程调用execexit。当子进程调用其它程序时父进程才继续运行。但这容易引起死锁,因为如果子进程的运行是依赖于父进程的运行状态的话,就会发生死锁。

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;
}

发表评论