日期:2014-05-16 浏览次数:21049 次
创建子进程有很多种方式,调用fork()和vfork()是其中的两种方式
就说说fork和vfork的不同之处吧。
fork:
父进程调用完fork成功以后创建一个子进程,而且这个子进程会拷贝一份父进程的数据空间,堆和栈空间。并且父子进程的内存空间是完全独立的,并不共享。父进程和子进程谁先执行是不确定的。
vfork:
父进程调用完vfork后同样创建一个子进程,但是不同之处在于,子进程会先运行,在遇到exec或exit之后父进程才能运行(也就是说子进程结束以后父进程才能运行),子进程没有拷贝一份父进程的地址空间,而是在父进程的地址空间中运行。
下面来个例子吧。
fork:
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
int main()
{
pid_t pid;
int value;
value = 10;
pid = fork();
if (pid < 0)
{
perror("fork failed!\n");
exit(0);
}
else if( pid == 0 )//child
{
value++;
}
else
{
waitpid(pid,NULL,0);
printf("value = %d\n", value);
}
return 0;
}
$ ./a.outvfork:
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
int main()
{
pid_t pid;
int value;
value = 10;
pid = vfork();
if (pid < 0)
{
perror("fork failed!\n");
exit(0);
}
else if( pid == 0 )//child
{
value++;
_exit(0);
}
else
{
printf("value = %d\n", value);
}
return 0; ~
$ ./a.out
value = 11
很明显两次打印的结果不同了,可以看出fork后的父子是不共享内存空间的,而vfork后子进程是在父进程地址空间运行的,共用内存空间的。
大家可能看得了我在第二个程序的子进程中用了_exit(0)来退出进程而不是用常用的exit(0)来退出。下面就来讲下exit和_exit的区别。
当调用exit(0)以后,系统会清洗缓冲区,并且关闭全部的标准I/O流。而调用_exit(0)后缓冲区冲不冲洗得看具体实现,在UNIX系统中,是不清洗的。
一个简单的例子:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
int main()
{
int value;
value = 1;
printf("%d",value);
_exit(0);
}
$ ./a.out
$
什么也没有输出来
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
int main()
{
int value;
value = 1;
printf("%d",value);
exit(0);
}
$ ./a.out
1$