在Linux中,fork函数的功能就是在一个进程中创建一个新的进程,当前调用fork函数的进程就是产生的新进程的父进程,新进程在以下也称为子进程。在新进程生成之后就会在系统中开始执行。

函数原型:pid_t fork(void); 其中pid_t 是一个long。

pid_t fork(void); 

  在父进程中,返回值是子进程的进程ID,而在子进程中,返回值则是0,所以可以通过判断fork函数的返回值来判断当前执行的是父进程还是子进程。

  创建之后的子进程与父进程执行相同的程序段,但是拥有不同的堆栈段以及数据段,但是子进程中堆栈段和数据段都是父进程的完全复制,直到调用exec()函数簇让子进程去执行的新的代码,子进程就完全拥有了属于自己的代码段、堆栈段和数据段。

  在这个过程中,期初的Linux系统,确实是将父进程的所有内存进行复制产生新的进程映像,但太浪费内存了,所以现在并不会直接复制父进程的所有内存,而是子进程与父进程共享代码段,子进程的一系列进程级列表都指向父进程的页表,在exec()函数调用之后,再对子进程的页表进行相应的调整,这个操作就用到了写时复制技术(copy-on-write),也就是从这一刻起,子进程开始独立地执行新的代码段。

pid_t childPid;
switch(childPid = fork()) {
case -:
//error
break; case :
//child process
break; default:
//father process comes here after fork()
}

  当进程创建失败时,fork()的返回值存放在errno中,当其为EAGAIN是,原因是进程的数目超过了当前允许创建的进程数量的最大值;当其为ENOMEM,表示内存不足,无法配置核心所需的数据结构空间。

在Linux中,与fork()功能类似还有一个函数vfork(),这个函数也是创建一个进程,但是与fork()有一些不同,vfork()的设计理念是在创建新进程之后,阻塞父进程,用子进程直接执行新的代码,并且使用父进程的内存,直到子进程执行完毕返回,父进程才会继续执行。在早期的Linux中vfork()比fork()更高效,因为vfork()不会只会复制父进程的部分内容,但是在现在的Linux系统中,由于写时复制技术,fork()的效率大大提高,甚至和fork()不相上下,所以尽量避免使用vfork()函数。而且由于vfork()创建的进程与父进程共享内存,极有可能出现各种未知的错误,这也是避免使用vfork()的重要原因。

最新文章

  1. VLAN 间路由的几种方法
  2. CSS行高——line-height
  3. WPF学习之路(三) 属性与依赖
  4. HTML 学习笔记 CSS(轮廓)
  5. VMware配置回环地址用于测试
  6. 基于TFTP协议的远程升级设计
  7. bzoj 3597: [Scoi2014]方伯伯运椰子
  8. Django—第三方引用
  9. IO多路复用和local概念
  10. Android RadioGroup中设置默认选中RadioButton 后,选中两个的问题 解决方法
  11. 蒜厂年会|计蒜客2019蓝桥杯省赛 B 组模拟赛(一)
  12. Add custom field in Material Master
  13. linux常用文本编缉命令(strings/sed/awk/cut)
  14. uva-11129-分治
  15. x86寄存器总结
  16. angularjs中的单选框绑定数据注意事项
  17. Windows批处理程序bat
  18. linux进程、调度、线程、进程上下文等几点理解
  19. shell基础篇(一)从hello world开始
  20. Linux 安装交叉编译工具链

热门文章

  1. unable to resolve module react-native-gesture-handler from
  2. 计算kdj
  3. springboot+maven多模块工程dependency not found
  4. JDBC测试计划-连接mysql
  5. 100-days: twenty-one
  6. Python中日期和时间格式化输出的方法
  7. pytho命名规范
  8. Spring 文件上传MultipartFile 执行流程分析
  9. AFNetworking Delete请求,报参数为空的错误
  10. taro Object(...) is not a function 版本更新后,H5端运行出错