fork和vfork都是用来创建进程的API函数,下面就进行比较分析:
fork函数:
用于创建子进程。
头文件:#include <sys/types.h>
#include <unistd.h>
原型:pid_t fork(void)
返回值:如果在父进程中,返回子进程的进程号;在子进程中返回0;错误返回-1。
注意:fork()调用执行一次后返回两个值,本质是:对于父进程,将返回子进程的进程号;对于子进程,fork()就返回0。在fork()之后,子进程和父进程都会继续执行fork()调用之后的指令。子进程是父进程的副本,它将获得父进程的数据空间、堆和栈的副本,因为这些是副本,所以父子进程并不共享这个部分的内存,即子进程和父进程中的同名变量进行修改并不会影响其在父进程中的值。
vfork函数:
用于建立新的进程。
头文件:#include <unistd.h>
原型:pid_t vfork(void)
返回值:成功,如果在父进程中,返回新建立的子进程代码;如果在新建的子进程中则返回0;如果失败返回-1。
注意:vfork创建的子进程与父进程共享地址空间,即子进程完全运行在父进程的地址空间上,如果子进程改变某个变量,也会影响到父进程。而且vfork创建的子进程必须退出,否则子进程将不能结束,而子进程又是先于父进程运行的,结束会影响父进程的运行。
fork()和vfork()的区别:
1、fork()子进程拷贝父进程的数据空间、堆和栈;而vfork()子进程与父进程共享数据空间;
2、fork()父子进程的执行次序不确定,而vfork()保证子进程先运行,再调用exit()或exec()退出,在退出前,两个进程数据是共享的;
3、vfork()保证子进程先运行,在调用exec()或exit()之后,父进程才会被调度运行。如果在调用这两个函数之前子进程依赖于父进程的进一步,会造成死锁;
4、当需要改变共享数据中变量的值,则拷贝父进程。
以下是fork和vfork创建新的进程的示例比较:
vfork:
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <stdlib.h>
int main()
{
gid_t pid;
int count = 0;
pid = vfork();
count++;
printf("count = %d\n",count);
if(pid == -1)
{
printf("Error!\n");
exit(1);
}
else
{
if(pid == 0)
{
printf("In the parent process!\n");
}
else
{
printf("In the child process!\n");
exit(0);
}
}
printf("The count is %d\n",count);
return 0;
}
调试结果:
count = 1
In the parent process!
The count is 1
count = 1
In the child process!
更改count++的位置,放置在pid = fork()之前,则有下列的程序:
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <stdlib.h>
int main()
{
gid_t pid;
int count = 0;
count++;
pid = vfork();
printf("count = %d\n",count);
if(pid == -1)
{
printf("Error!\n");
exit(1);
}
else
{
if(pid == 0)
{
printf("In the parent process!\n");
}
else
{
printf("In the child process!\n");
exit(0);
}
}
printf("The count is %d\n",count);
return 0;
}
调试结果:
count = 1
In the parent process!
The count is 1
count = 0
In the child process!
fork:
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <stdlib.h>
int main()
{
gid_t pid;
int count = 0;
pid = fork();
count++;
printf("count = %d\n",count);
if(pid == -1)
{
printf("Error!\n");
exit(1);
}
else
{
if(pid == 0)
{
printf("In the parent process!\n");
}
else
{
printf("In the child process!\n");
exit(0);
}
}
printf("The count is %d\n",count);
return 0;
}
调试结果:
count = 1
In the parent process!
The count is 1
count = 1
In the child process!
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <stdlib.h>
int main()
{
gid_t pid;
int count = 0;
count++;
pid = fork();
printf("count = %d\n",count);
if(pid == -1)
{
printf("Error!\n");
exit(1);
}
else
{
if(pid == 0)
{
printf("In the parent process!\n");
}
else
{
printf("In the child process!\n");
exit(0);
}
}
printf("The count is %d\n",count);
return 0;
}
调试结果:
count = 1
In the parent process!
The count is 1
count = 1
In the child process!