fork与vfork的用法与区别

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了fork与vfork的用法与区别相关的知识,希望对你有一定的参考价值。

fork和vfork都用于创建进程

  1. fork函数的作用是复制一个进程,当一个进程调用它,完成后就出现两个几乎一模一样的进程,也由此得到一个新的进程,称为子进程。原来的进程称为父进程。子进程是父进程的一个拷贝,即子进程从父进程得到了数据段和堆栈段的拷贝,这些需要分配新的内存;而对于只读的代码段,通常使用共享内存的方式访问。

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

int main()
{
        int count=0;
        pid_t pid;
        pid=fork();     // 创建一个子进程
        if(pid<0)
        {
                printf("error in fork!");
                exit(1);
        }
        else if(pid==0)
        {
                printf("I am the child process,the count is %d,my process ID %d,pid=%d\n",++count,getpid(),pid);
                exit(0);
        }
        else
                printf("I am the parent process,the count is %d,my process ID %d,pid=%d\n",count,getpid(),pid);

        return 0;
}

运行结果:

I am the parent process,the count is 0,my process ID 2765,pid=2766

I am the child process,the count is 1,my process ID 2766,pid=0

两个进程的区别在于他们的pid值不同。fork调用的一个奇妙之处在于他仅仅被调用一次,却能返回两次,他可能有3中不同的返回值

    在父进程中,fork返回新创建的子进程的ID

    在子进程中,fork返回0

    如果出现错误,fork返回一个负值

fork可能出错的原因有两种:一是当前的进程数已经达到系统规定的上限,这时errno的值被设置为EAGAIN;二是系统的内存不足,这时的errno的值被设置为ENOMEM

2.vfork

与fork相同,也是用于创建一个新的进程。但是vfork与fork是有区别的。fork要拷贝父进程的数据段,而vfork则不需要完全拷贝父进程的数据段,在子进程没有调用exec或exit之前,子进程与父进程共享数据段。fork不对父进程的执行次序进行任何限制;而vfork在调用中,子进程先运行,父进程挂起,直到子进程调用了exec或者exit之后,父进程的执行次序才不再有限制。

vfork创建子进程与父进程之间共享数据段

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

int main(void)
{
        int count=1;
        int child;
        printf("Before create son, the father‘s count is %d\n",count);
        child=vfork();  //创建了一个新的进程,此时有两个进程在运行
        if(child < 0)
        {
                printf("error in vfork!\n");
                exit(1);
        }
        if(child==0)
        {
                printf("This is son,his pid id %d and the count is %d\n",getpid(),++count);
                exit(1);
        }
        else
        {
                printf("After son, This is father,his pid is %d and the count is %d, and the child is %d\n",getpid(),count,child);
        }

        return 0;
}

Before create son, the father‘s count is 1

This is son,his pid id 2809 and the count is 2

After son, This is father,his pid is 2808 and the count is 2, and the child is 2809

在子进程中修改了count值,但是在父进程中输出count的值也是2,这说明子进程和父进程是共享count的,也就是说,由vfork创建出来的子进程与父进程之间是共享内存区的。

    另外,由vfork创造出来的子进程还会导致父进程挂起,除非子进程执行了exit或者exec才会唤起父进程,例如:

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

int main()
{
        int count = 1;
        int child;
        printf("Before create son,the father‘s connt is %d\n",count);
        if(!(child=vfork()))
        {
                int i;
                for(i=0;i<100;i++)
                {
                        printf("This is son,the i is %d\n",i);
                        if(i==10)exit(0);
                }
                printf("This is son, his pid is %d and the count is %d\n",getpid(),++count);
                exit(0);
        }
        else
        {
                printf("After son,This is father,his pid id %d and the count is %d and the child is %d\n",getpid(),count,child);
        }
        return 0;
}

执行结果如下:

Before create son,the father‘s connt is 1

This is son,the i is 0

This is son,the i is 1

This is son,the i is 2

This is son,the i is 3

This is son,the i is 4

This is son,the i is 5

This is son,the i is 6

This is son,the i is 7

This is son,the i is 8

This is son,the i is 9

This is son,the i is 10

After son,This is father,his pid id 2720 and the count is 1 and the child is 2721

从中可以看出,父进程总是等子进程执行完毕后才开始执行的。

本文出自 “帆布鞋也能走猫步” 博客,请务必保留此出处http://9409270.blog.51cto.com/9399270/1869622

以上是关于fork与vfork的用法与区别的主要内容,如果未能解决你的问题,请参考以下文章

Linux中fork,vfork和clone详解(区别与联系)

linux 进程创建clonefork与vfork

fork 与 vfork

fork vfork clone学习

进程控制fork与vfork

APUE学习之进程控制 - fork 与 vfork