fork与vfork的使用和区别

fork和vfork()函数都可以创建一个新的进程。主要的两个区别如下:

1.vfork()函数在创建子进程时,不会复制父进程的所有资源,相反,子进程共享父进程的内存,

   直至其成功执行了exec()或者调用_exit()退出;

2.vfork()函数创建的子进程最后必须调用_exit()函数才能正确退出子进程,不能使用exit()函数。

为了更便于理解fork()和vfork()两个函数创建的子进程的区别,可以使用如下两个测试程序,来分别运行看一下:

#include <sys/types.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

int idata = 111;

int main()
{
        int istack = 222;

        pid_t ChildPid;

        switch (ChildPid = fork())<span style="white-space:pre">	</span>//使用fork创建进程
        {

                case -1:
                        printf("fork create error!\n");
                        exit(1);

                case 0:
                        idata *= 3;
                        istack *= 3;
                        printf("Child process, PID = %d,idata = %d,istack = %d\n",getpid(),idata,istack);

                default:
                        sleep(3);
                        printf("Parent process, PID = %d,idata = %d,istack = %d\n",getpid(),idata,istack);
        }

        return 0;
}
运行结果:



#include <sys/types.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

int idata = 111;

int main()
{
        int istack = 222;

        pid_t ChildPid;

        switch (ChildPid = vfork())<span style="white-space:pre">	</span>//使用vfork创建进程
        {

                case -1:
                        printf("fork create error!\n");
                        exit(1);

                case 0:
                        idata *= 3;
                        istack *= 3;
                        printf("Child process, PID = %d,idata = %d,istack = %d\n",getpid(),idata,istack);
                        _exit(0);<span style="white-space:pre">	</span>//vfork创建的子进程必须调用_exit()函数才能正确退出

                default:
                        sleep(3);
                        printf("Parent process, PID = %d,idata = %d,istack = %d\n",getpid(),idata,istack);
        }

        return 0;
}
运行结果:



如上所示的两组程序逻辑相同,只是分别调用了fork和vfork创建子进程。通过结果,可以看出,在第一个程序(fork)的结果中,在子进程中修改了idata和istack的值,等到再进入父进程时,值没有发生改变;在第二个程序(vfork)的结果中,在子进程中修改了idata和istack的值,等到再进入父进程时,值发生了改变

通过这个比较,可以总结如下:

1.fork()创建的子进程拥有了自己的栈和数据段拷贝,而且,在子进程中对父进程变量的修改,不会影响父进程;

2.vfork()创建的子进程共享父进程的内存,所以在子进程中对父进程变量的修改,会影响父进程。

另外关于vfork()函数,还想多说几句。不知道大家有没有看过Michael Kerrisk先生编著的《Linux/UNIX系统编程手册(上册)》这本书。在第24章“进程的创建”,第三小节“系统调用vfork()”中,作者特别写了几句:“鉴于vfork()的怪异语义可能会导致一些难以察觉的程序缺陷(bug),除非能给性能带来重大提升(这种情况发生的概率极小),否则应当尽量避免使用这一调用”对于这几句,目前我还没有什么太深的理解。关于vfork的bug这一点,不知道哪位大神有这方面的经验和教训,可以互相分享讨论一下,大家共同注意。

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值