fork 和 vfork函数详解

fork 和 vfork函数详解

​ 先说说区别,两者都是创建一个新的进程:

​ 1.使用fork时,父进程和子进程的执行顺序是随机的(时间片轮转调度决定),而使用vfork时,子进程总是先执行,待子进程结束再执行父进程。

​ 2.使用fork时,父进程将自己的数据复制一份拿给子进程,即子进程是父进程的完全副本,而使用vfork时,子进程共享父进程的数据。

fork函数

​ 作用:创建一个新的进程,实际上是创建一个父进程的完全副本,即将父进程的数据完全拷贝一份给子进程,子进程和父进程的执行顺序是随机的,一般可能看见父进程先于子进程执行是因为创建了子进程后,时间片可能仍然是父进程所有,因此父进程先执行。

函数原型:
    pid_t fork();
头文件:
    #include <sys/types.h>
    #include <unistd.h>
函数功能:
    创建一个进程;
返回值:
    -1:失败
     0:子进程返回0>0:父进程返回一个大于0的的整数,该整数是子进程的进程id

fork实例1:

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

int main()
{
    pid_t pid = fork();
    
    if(pid == -1)
    {
        perror("fork");
        return -1;
    }
    
    if(pid == 0)//子进程,pid=0
    {	
        printf("I'm child process,my pid is %d\n", getpid());
    }
    else//父进程,pid>0
    {
        printf("I'm parent process,my pid is %d, my child's pid is %d\n", getpid(), pid);
    }
    
    return 0;
}

在这里插入图片描述

fork实例2:让父进程阻塞,等待子进程运行结束后再运行

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

int main()
{
    pid_t pid = fork();
    if(pid == -1)
    {
        perror("fork");
        return -1;
    }
    
    if(pid > 0)
    {
        //父进程休眠3秒
        sleep(3);
        printf("I'm parent process,my pid is %d, my child's pid is %d\n", getpid(), pid);
    }
    else
    {
        printf("I'm child process,my pid is %d\n", getpid());
    }
    
    return 0;
}
终端编译运行:
	gcc fork.c -o fork
	./fork

在这里插入图片描述

vfork函数

​ 作用:vfork函数也是创建一个新的进程,但使用该函数后,子进程先执行,子进程执行结束后再执行父进程,且子进程共享父进程的数据。

函数原型:
    pid_t vfork();
头文件:
    #include <sys/types.h>
    #include <unistd.h>
函数功能:
    创建一个进程;
返回值:
    -1:失败
     0:子进程返回0>0:父进程返回一个大于0的的整数,该整数是子进程的进程id
    
tips:使用该函数,子进程先运行,子进程结束后再运行父进程。

vfork实例1:

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

int main()
{
        pid_t pid = vfork();
        if(pid == -1) 
        {
                perror("vfork");
                return -1; 
        }

        if(pid > 0)
        {
                printf("I'm parent process!my pid is %d,my child's pid is %d\n", getpid(), pid);
        }
        else
        {   
                printf("I'm child process!my pid is %d\n", getpid());
                exit(0);
        }

        return 0;
}

在这里插入图片描述

vfork实例2:让子进程休眠3秒钟

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

int main()
{
        pid_t pid = vfork();
        if(pid == -1) 
        {
                perror("vfork");
                return -1; 
        }

        if(pid > 0)
        {
                printf("I'm parent process!my pid is %d,my child's pid is %d\n", getpid(), pid);
        }
        else
        {   
                sleep(3);//子进程休眠3s
                printf("I'm child process!my pid is %d\n", getpid());
                exit(0);
        }

        return 0;
}

在这里插入图片描述

由实例1和实例2可看出,即使是让子进程休眠3秒,父进程依旧不会先执行,而是等待子进程先执行完毕后再执行父进程。

小tips:

​ 这里我遇见一个小问题,当未在子进程中添加exit()函数时,程序最后运行会报一个段错误!!! 经过查证得知,vfork()创建子进程成功后是严禁使用return的,只能调用exit()或者exec族的函数,否则后果不可预料,在main函数里return和exit()效果一样是有前提的:没有调用vfork。

详细说:

  1. return返回函数值,是关键字;exit是一个函数。

  2. return是语言级别的,它表示了调用堆栈的返回;而exit是系统调用级别的,它表示了一个进程的结束。

  3. return是函数的退出(返回);exit是进程的退出。

  4. return是C语言提供的,exit是操作系统提供的(或者函数库中给出的)。

  5. return用于结束一个函数的执行,将函数的执行信息传出个其他调用函数使用;exit函数是退出应用程序,删除进程使用的内存空间,并将应用程序的一个状态返回给OS,这个状态标识了应用程序的一些运行信息,这个信息和机器和操作系统有关,一般是 0 为正常退出,非0 为非正常退出。

回);exit是进程的退出。

  1. return是C语言提供的,exit是操作系统提供的(或者函数库中给出的)。

  2. return用于结束一个函数的执行,将函数的执行信息传出个其他调用函数使用;exit函数是退出应用程序,删除进程使用的内存空间,并将应用程序的一个状态返回给OS,这个状态标识了应用程序的一些运行信息,这个信息和机器和操作系统有关,一般是 0 为正常退出,非0 为非正常退出。

6. 非主函数中调用return和exit效果很明显,但是在main函数中调用return和exit的现象就很模糊,多数情况下现象都是一致的。
  • 2
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

昌昌.

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值