fork与vfork的区别

本文详细解释了vfork与fork两种进程创建方式的区别,重点介绍了vfork如何通过暂时共享地址空间来提高效率,并讨论了使用vfork时可能出现的死锁问题及解决方法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

参考文章:http://blog.youkuaiyun.com/jianchi88/article/details/6985326

 

1.  fork  ():子进程拷贝父进程的数据段,代码段
    vfork ( ):子进程与父进程共享数据段

2.  fork ()父子进程的执行次序不确定
    vfork 保证子进程先运行,在调用exec 或exit 之前与父进程数据是共享的,在它调用exec
     或exit 之后父进程才可能被调度运行。 

3.  vfork ()保证子进程先运行,在她调用exec 或exit 之后父进程才可能被调度运行。如果在
   调用这两个函数之前子进程依赖于父进程的进一步动作,则会导致死锁。 

 

案例

 

    #include<sys/types.h>  
    #include<unistd.h>  
    #include<stdio.h>  
      
    int main()  
    {  
        pid_t pid;  
        int cnt = 0;  
        pid = vfork();  
        if(pid<0)  
            printf("error in fork!\n");  
        else if(pid == 0)  
        {  
            cnt++;  
            printf("cnt=%d\n",cnt);  
            printf("I am the child process,ID is %d\n",getpid());  
        }  
        else  
        {  
            cnt++;  
            printf("cnt=%d\n",cnt);  
            printf("I am the parent process,ID is %d\n",getpid());  
        }  
        return 0;  
    }  

执行结果:

 

 

cnt=1  
I am the child process,ID is 4711  
cnt=1  
I am the parent process,ID is 4710  
段错误 


本来vfock()是共享数据段的,结果应该是2,为什么不是预想的2 呢?先看一个知识点:
vfork 和fork 之间的另一个区别是:vfork 保证子进程先运行,在她调用exec 或exit 之
后父进程才可能被调度运行。如果在调用这两个函数之前子进程依赖于父进程的进一步动
作,则会导致死锁。
vfork ()创建子进程并没有调用exec 或exit,
所以最终将导致死锁。 

 

应该改成如下:

 

    #include<sys/types.h>  
    #include<unistd.h>  
    #include<stdio.h>  
      
    int main()  
    {  
        pid_t pid;  
        int cnt = 0;  
        pid = vfork();  
        if(pid<0)  
            printf("error in fork!\n");  
        else if(pid == 0)  
        {  
            cnt++;  
            printf("cnt=%d\n",cnt);  
            printf("I am the child process,ID is %d\n",getpid());  
           _exit(0);  
        }  
        else  
        {  
            cnt++;  
            printf("cnt=%d\n",cnt);  
            printf("I am the parent process,ID is %d\n",getpid());  
        }  
        return 0;  
      
    }  


结果:

 

 

cnt=1  
I am the child process,ID is 4711  
cnt=2  
I am the parent process,ID is 4710  


网上抄的一段,可以再理解理解:
为什么会有vfork,因为以前的fork 很傻, 它创建一个子进程时,将会创建一个新的地址
空间,并且拷贝父进程的资源,而往往在子进程中会执行exec 调用,这样,前面的拷贝工
作就是白费力气了,这种情况下,聪明的人就想出了vfork,它产生的子进程刚开始暂时与
父进程共享地址空间(其实就是线程的概念了),因为这时候子进程在父进程的地址空间中
运行,所以子进程不能进行写操作,并且在儿子 霸占”着老子的房子时候,要委屈老子一
下了,让他在外面歇着(阻塞),一旦儿子执行了exec 或者exit 后,相 于儿子买了自己的
房子了,这时候就相 于分家了。

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值