进程的创建-------fork与vfork

目录

fork函数

fork的使用

vfork函数

fork() 与 vfock() 都是创建一个进程,那它们有什么区别呢?

进程的正常终止方法?

进程的异常终止

为什么vfork()子进程中可以调用_exit(),却不可以调用exit(),也不可以直接return呢?


fork函数

fork的使用

头文件  #include<unistd.h>

函数原型  pid_t fork(void)

fork功能  创建子进程 父子进程代码共享,数据个自开辟空间,私有一份(采用写时拷贝)

结果  一次调用 有两个返回值,它可能有三种不同的情况

1.    在父进程中,fork返回新创建的子进程的PID。父进程可以创建多个子进程.根据子进程的pid来区分子进程

2.    在子进程中,fork返回0;

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

一般来说,fork之后父、子进程执行顺序是不确定的,这取决于内核调度算法。进程之间实现同步需要进行进程通信。

一个父进程希望子进程同时执行不同的代码段,这在网络服务器中常见——父进程等待客户端的服务请求,当请求到达时,父进程调用fork,使子进程处理此请求。

一个进程要执行一个不同的程序,一般fork之后立即调用exec

进程调用fork,在内核中,进行以下操作:

  • 分配新的内存块和内核数据给子进程
  • 将父进程部分数据结构内容拷贝至子进程
  • 添加子进程到系统进程列表中
  • fork返回,进行调度器调度

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

 

vfork函数

#include<sys/types.h>

#include<unistd.h>

pid_t vfork(void)

功能:创建子进程

成功:子进程中返回 0,父进程中返回子进程 ID。pid_t,为无符号整型。失败:返回 -1。

fork() 与 vfock() 都是创建一个进程,那它们有什么区别呢?

1)fork(): 父子进程的执行次序不确定。

vfork():保证子进程先运行,在它调用 exec(进程替换) 或 exit(退出进程)之后父进程才可能被调度运行。

2)fork(): 子进程拷贝父进程的地址空间,子进程是父进程的一个复制品。

vfork():子进程共享父进程的地址空间(准确来说,在调用 exec(进程替换) 或 exit(退出进程) 之前与父进程数据是共享的)子进程不会完全复制父进程的地址空间,它会在父进程的地址空间中运行。vfork创建的子进程,共享的是父进程当前栈帧的地址空间。

进程的正常终止方法?

  • 调用_exit()      

   _exit()调用之后会立即进入内核

  • 调用exit()

清理I/O缓冲区,关闭文件描述符后再退出进程 

  • 直接return

语言级别的,它表示了调用堆栈的返回,

如果是在主函数main, 自然也就结束当前进程

进程的异常终止

  • ctrl + C

为什么vfork()子进程中可以调用_exit(),却不可以调用exit(),也不可以直接return呢?

exit()是对_exit()的封装,它自己在调用_exit()前会做很多清理工作,其中包括刷新并关闭当前进程使用的流缓冲(比如stdio.h里面的printf等),由于vfork()的子进程完全共享了父进程地址空间,子进程里面的流也是共享的父进程的流,所以子进程里面是不能做这些事的。

直接return就更不行,子进程return以后,会从当前函数的外部调用点后面继续执行,这后面子进程可能将会执行很多语句,结果就没法预料了。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值