日期:2014-05-16  浏览次数:20748 次

vfork函数
程序里有两个exit(0),如果屏蔽掉,结果子进程多运行一遍,这是什么原因呢?
[code=C/C++][/code]#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <math.h>

int main(void)
{
pid_t child;

/* 创建子进程 */
if((child=vfork())==-1)
{
printf("Fork Error : %s\n", strerror(errno));
exit(1);
}
else 
if(child==0) // 子进程
{
sleep(1); //子进程睡眠一秒
printf("I am the child: %d\n", getpid());
//exit(0);
}
else //父进程
{
printf("I am the father:%d\n",getpid());
//exit(0);
}
}

------解决方案--------------------
C/C++ code

   Linux Description
       vfork(), just like fork(2), creates a child process of the calling process.  For details and return value and errors, see fork(2).

       vfork()  is  a special case of clone(2).  It is used to create new processes without copying the page tables of the parent process.  It may be useful in
       performance-sensitive applications where a child is created which then immediately issues an execve(2).

       vfork() differs from fork(2) in that the parent is suspended until the child terminates (either normally, by  calling  _exit(2),  or  abnormally,  after
       delivery  of a fatal signal), or it makes a call to execve(2).  Until that point, the child shares all memory with its parent, including the stack.  The
       child must not return from the current function or call exit(3), but may call _exit(2).

------解决方案--------------------
子进程多运行一遍?你是想说printf的输出多了一行吧?

vfork的子进程在exit或者exec之前是运行在父进程地址空间中
如果vfork的子进程调用exit会影响父进程的行为,因为exit会刷新并关闭I/O输出流(c库的实现不同可能有不同),所以vfork的子进程调exit后,父进程的I/O流也被关闭了,所以父进程的printf无法输出

注释掉了exit,自然父子进程的printf都能输出了
------解决方案--------------------
vfork在不同的unix/linux版本上的实现有微妙的语议差别,
至少你这个例子在我的ubuntu上会异常退出

I am the child: 18293, father is 18292
I am the father:18292
test: cxa_atexit.c:100: __new_exitfn: Assertion `l != ((void *)0)' failed.
Aborted

你可以把子进程的父进程的pid也打出来看看倒底第二个子进程的父进程是哪个.