本文分享了Linux vfork与fork简单对比分析,分享给大家,具体如下:
fork相关问题:
一、fork基础了解
fork作用为创建一个子进程,在使用了fork命令后,内核会分配新的内存块和数据结构给子进程,并且将父进程的部分数据结构内容拷贝到子进程,最后再将子进程添加到系统进程列表中,添加完成后fork返回,开始调度。
头文件:#include < unistd.h >
函数原型:pid_t fork( )
返回值:返回值大于0则当前进程为父进程,等于0代表为子进程,小于零代表创建子进程失败。
通过一个例子来了解:
#include <stdio.h> #include <unistd.h> int main() { int tmp = 5; pid_t res = fork(); if(res < 0){ //fork失败 perror("fork"); }else if(res == 0){ //该进程为子进程 printf("im child[%d],fasther is %d,tmp is %d./n",getpid(),getppid(),tmp++); }else{ //该进程为父进程 printf("im father[%d],tmp is %d./n",getpid(),tmp++); } p
运行结果:
im father[3128],tmp is 5.
tmp = 6 im child[3129],fasther is 1,tmp is 5. tmp = 6相关问题小结:
通过结果很明显的能看出本次调用中,先执行父进程,对应pid为3128,在父进程中tmp++,所以输出为6;关键问题在于子进程,有两个关键点。
①为什么结果中子进程父亲pid为1:通过输出我们能看出父进程先执行完成后才执行的子进程,也就是说当子进程执行时父进程已结束,此时该子进程相当于一个孤儿进程,被pid为1也就是Init进程所管理,所以子进程的ppid为1;
②为什么子进程最后输出tmp值还为6: fork进程采用的是写时拷贝,父子进程一开始共享一片内存区域,但是只有有一方要对数据进行修改,则再开辟一块空间,防止相互修改影响。所以在上述代码中,虽说是一个tmp,其实内存中各自保留了一份值。
二、关于fork过程中写时拷贝:
这下就不难看出,父子进程数据段和代码段开始时是共享一块对应的内存,当一方尝试写入时,便产生了写时拷贝。需要注意的是:fork之前,父进程独立执行,fork之后,父子两个执行流分别执行,至于谁先执行,由调度器决定。可通过下面例子很明显的看出是从fork之后才分别执行。
#include <stdio.h> #include <unistd.h> int main() { int tmp = 5; printf("There is fork before/n"); pid_t res = fork(); if(res < 0){ //fork失败 perror("fork"); }else if(res == 0){ //该进程为子进程 printf("im child[%d],tmp is %d./n",getpid(),tmp++); }else{ //该进程为父进程 printf("im father[%d],tmp is %d./n",getpid(),tmp++); } printf("tmp = %d/n",tmp); return 0; }
输出结果:
There is fork before
im father[3625],tmp is 5.
tmp = 6
im child[3626],tmp is 5.
tmp = 6
三、fork调用失败的原因:
新闻热点
疑难解答