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

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

时间: 2024-08-09 02:07:54

fork与vfork的用法与区别的相关文章

fork()、vfork()、clone()的区别

因为生活的复杂,这是一个并行的世界,在同一时刻,会发生很多奇妙的事情,北方下雪,南方下雨,这里在吃饭,那边在睡觉,有人在学习,有人在运动,所以这时一个多彩多姿的世界,每天都发生着很多事情,所以要想很好的表现这个世界,协调完成一件事儿,就得用到多进程或者多线程.所以进程是程序猿一定会接触到的一个东西,他能使我们的程序效率提高,高效的完成多任务,并行执行.下面主要看看产生进程或线程的三个函数. fork,vfork,clone都是linux的系统调用,这三个函数分别调用了sys_fork.sys_v

linux 进程创建clone、fork与vfork

目录: 1.clone.fork与vfork介绍 2.fork说明 3.vfork说明 4.clone说明5.fork,vfork,clone的区别 内容: 1.clone.fork与vfork介绍 Linux下的进程与线程相同点是都有进程控制块(PCB,具体的类是task_struct).区别在于一个有独立的进程资源,一个是共享的进程资源.除了内核线程是完全没有用户空间.进程资源包括进程的PCB.线程的系统堆栈.进程的用户空间.进程打开的设备(文件描述符集)等. Linux的用户进程不能直接被

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

fork,vfork,clone Unix标准的复制进程的系统调用时fork(即分叉),但是Linux,BSD等操作系统并不止实现这一个,确切的说linux实现了三个,fork,vfork,clone(确切说vfork创造出来的是轻量级进程,也叫线程,是共享资源的进程) 系统调用 描述 fork fork创造的子进程是父进程的完整副本,复制了父亲进程的资源,包括内存的内容task_struct内容 vfork vfork创建的子进程与父进程共享数据段,而且由vfork()创建的子进程将先于父进程

Linux之fork与vfork区别

创建一个新进程的方法只有由某个已存在的进程调用fork()或vfork() 1.fork()函数 返回值:成功:父进程:返回子进程的PID 子进程:返回0 失败:父进程返回-1 子进程是父进程的一个拷贝.即子进程从父进程得到数据段和堆.栈段的拷贝,这些需要分配新的内存(不是与父进程共享,而是单独分配内存):而对于只读的代码段,通常使用共享内存的方式访问. fork返回后,子进程和父进程都从调用fork函数的下一条语句开始执行. 由于子进程与父进程的运行是无关的,所以,父进程可先于子进程运行,子进

c语言exit和return区别,在fork和vfork中使用

c语言exit和return区别,在fork和vfork中使用 exit函数在头文件stdlib.h中. exit(0):正常运行程序并退出程序: exit(1):非正常运行导致退出程序: return():返回函数,若在main主函数中,则会退出函数并返回一值,可以写为return(0),或return 0. 1. return返回函数值,是关键字:exit是一个函数. 2. return是语言级别的,它表示了调用堆栈的返回:而exit是系统调用级别的,它表示了一个进程的结束. 3. retu

fork与vfork区别及用exit于return返回时的区别

fork()与vfork()区别: 1.fork()父子进程的执行次序不确定,它们的调度顺序由调度器说了算.而vfork()保证子程序先运行,在调用exit或者exec前父子进程数据共享,在子进程调用exit或exec退出后父进程才能被调度运行. 2.fork()子进程会拷贝父进程的数据段,而vfork()父子进程共享数据段. return与exit返回时的区别: 首先结束子进程的调用需要用exit(),因没有修改函数栈,若在vfork中return,那就意味在main函数中return,这是因

UNIX高级环境编程(9)进程控制(Process Control)- fork,vfork,僵尸进程,wait和waitpid

本章包含内容有: 创建新进程 程序执行(program execution) 进程终止(process termination) 进程的各种ID ? 1 进程标识符(Process Identifiers) 每个进程都有一个唯一的标识符,进程ID(process ID). 进程的ID是可重用的,如果一个进程被终止,那么它的进程ID会被系统回收,但是会延迟使用,防止该进程ID标识的新进程被误认为是以前的进程. 三个特殊ID的进程: Process ID 0:调度者进程,内核进程. Process

fork和vfork,return和exit的理解

fork和vfork的差别: 1.fork是创建一个子进程,并把父进程的内存数据copy到子进程中. vfork是创建一个子进程,并和父进程的内存数据share一起. 2.vfork是这样的工作的: (1).保证子进程先执行. (2).当子进程调用exit()或exec()后,父进程往下执行. 3.fork后来采用的优化技术,这样,对于fork后并不是马上拷贝内存,而是只有你在需要改变的时候,才会从父进程中拷贝到子进程中,这样fork后立马执行exec的成本就非常小了.而vfork因为共享内存所

FILE、inode、fork和vfork

1.FILE文件指针 a>.指向进程用户区中的 FILE 结构的数据结构: b>.FILE 结构包括:I/O缓冲区.文件描述符(文件描述表的一个索引): c>.FILE 结构中含有文件描述符,可以使用 fopen 来获得文件指针,然后从文件指针获取文件描述符(文件描述符唯一,而文件指针不唯一,但指向的对象唯一): d>.FILE 结构函数可以看作是队 fd 直接操作的系统调用的封装,它的优点是带有I/O缓存,比 fd 具有跨平台性. 2.inode,软链接,硬链接 inode:记录