红联Linux门户
Linux帮助

linux c之创建进程fork和vfork函数之间的区别

发布时间:2017-01-15 10:41:14来源:linux网站作者:改变自己chenyu
1、函数简介
1)、得到当前的进程id
pid_t getpid(); 
 
2)、fork函数
要创建进程,必须调用fork函数, 系统调用fork用于派生一个进程,函数原型如下
#include<sys/types.h>  
#include<unistd.h>  
pid_t fork(void)  
若成功,父进程中返回子进程id,子进程返回0;若出错则返回-1,若出错返回0,要注意这是2次返回,由于在复制时复制了父进程的堆栈段,所以两个进程都停留在fork函数中,等待 返回。因此fork函数会返回两次,一次是在父进程中返回,另一次是在子进程中返回,这两次的返回值是不一样的,fork后就复制拉了一个进程,原来进程叫父进程,子进程是父进程的一个拷贝,子进程得到数据段和堆栈段的拷贝,父和子进程数据不共享。
 
3)、vfork函数
#include<sys/types.h>  
#include<unistd.h>  
pid_t vfork(void)  
另外一个创建进程的方法是vfork,vfork没有完全拷贝父进程的数据段,若成功,父进程中返回子进程id,子进程返回0;若出错则返回-1,若出错返回0,要注意这是2次返回,在子程序没有执行exex或exit之前,父进程和子进程数据共享,并且会先把父进程挂起来,这里是和fork函数的区别。
 
2、分别用fork和vfork函数创建子进程
1)、我们执行fork函数
#include<stdio.h>  
#include<unistd.h>  
#include<sys/types.h>  
#include<stdlib.h>  
int pid;  
void first_son_process() {  
int count = 0;  
int pid;  
pid = fork();  
if (pid < 0) {  
puts("fork fail");  
exit(1);  
} else if ( pid == 0) {  
printf("I am first child process, tht count is %d, my process id is %d\n", count, getpid());  
} else {  
printf("I am first parent process, tht count is %d, my process id is %d, son id %d\n", ++count, getpid(), pid);  
}  
}  
void second_son_process() {  
int count = 0;  
int pid = vfork();  
if (pid < 0) {  
puts("vfor fail");  
} else if (pid == 0) {  
printf("I am second child process, the count is %d, my process id is %d\n",  ++count, getpid());  
exit(1);  
} else {  
printf("I am second parent process, the count is %d, my process id is %d, son id %d\n", count, getpid(), pid);  
}  
}  
int main()  
{  
first_son_process();  
//    second_son_process();  
return 0;  
}  
~
 
2)、结果展示如下图
linux c之创建进程fork和vfork函数之间的区别
我们可以知道fork函数后创建了子进程,创建子进程返回0,父进程返回子进程id,父和子进程数据不共享。
 
3)、我们执行vfork函数
上面的代码需要注释掉用fork创建进程的方法,注释后,我们执行
 
4)、结果展示如下图
linux c之创建进程fork和vfork函数之间的区别
我们可以知道fork函数后创建了子进程,创建子进程返回0,父进程返回子进程id,子函数在执行exit(1)函数之前会把父进程挂起来,然后父和子进程数据共享。
 
4、分析总结
一、不同点
1、fork()用于创建一个新进程。由fork()创建的子进程是父进程的副本。即子进程获取父进程数据空间,堆和 栈的副本。父子进程之间不共享这些存储空间的部分。而vfork()创建的进程并不将父进程的地址空间完全复制到子进程中,因为子进程会立即调用exec (或exit)于是也就不会存放该地址空间。相反,在子进程调用exec或exit之前,它在父进程的空间进行。
2、vfork()与fork()另一个区别就是:vfork保证子进程先运行,在调用exec或exit之前与父进程数据是共享的,在它调用exec或exit之后父进程才可能被调度运行。
3 、vfork和fork之间的还有一个区别是: vfork保证子进程先运行,在她调用exec或exit之后父进程才可能被调度运行。如果在调用这两个函数之前子进程依赖于父进程的进一步动作,则会导致死锁。
 
二、相同点:
1、两者被调用一次,但是返回两次。两次返回的唯一区别是子进程的返回值是0,而父进程的返回值则是新子进程的进程ID。
 
本文永久更新地址:http://www.linuxdiyf.com/linux/27831.html