1、fork

首先我们先来回忆一下fork()函数:

  • 函数头文件:#include<unistd.h>
  • 函数原型:pid_t fork(void);其中pid_t是一个宏定义:#define pid_t int
  • 返回值:fork函数调用一次返回两次:
    • 在父进程中返回生成子进程的id(因为父进程不止拥有一个子进程);
    • 在子进程返回一个整数0(因为子进程只有一个父进程,可以通过调用getppid()得到父进程的进程ID);
    • 当然,如果创建失败,则返回-1;

2、复制内容

传统的fork函数之后会做这样的举动:

例:现在有一个进程1,在它的虚拟地址空间有:.text .data .bss heap stack。相应,内核会为这几个部分分配各自的物理空间。

我们现在用fork给进程1创建子进程,名为进程2—>现在子进程开始复制这几个部分,也就是虚拟地址空间—>为子进程的这几个部分分配物理块

可以看出:fork()之后会进行数据段,堆区,栈区的复制(.text共享)当然还有打开的文件描述符。

大家可以看到:传统的fork系统调用直接把所有的资源复制给新创建的进程,这种实现过于简单,并且效率低下,因为它拷贝的数据也许并不共享,如果这时子进程执行exec函数系统调用,那么拷贝也就没有什么意义了。

所以出现一个新的技术叫写时拷贝:

3、写时拷贝

fork()之后父进程的虚拟空间拷贝给子进程,在虚拟空间与物理页表建立映射的过程中使用了写时拷贝使得子进程共享父进程的物理空间,当父子进程其中一个对该区域进行写入时,子进程复制一个新的物理页表并建立映射,使得父子进程相互独立,同时节省了很多物理内存。子进程和父进程拥有相同的相互独立的虚拟空间(不同的进程都拥有自己独立的虚拟地址空间),但是却没有复制物理页表

在网上看到这样几句话分享给大家:

fork()之后exec之前两个进程用的是相同的物理空间(当然我们上面已经说过了),子进程的代码段,数据段、堆栈都是指向父进程的物理空间(物理页面为只读模式),也就是说,两者的虚拟空间不同,但对应的物理空间是一样的,如果不是exec,内核会为子进程的数据段、堆、栈分配物理空间,而代码段继续共享父进程的物理空间,而如果是因为exec,由于两者的代码不同,子进程的代码段也会分配到独立的物理空间。

接下来我们再来看一下vfork函数,看看vfork函数和fork函数有什么区别呢?

4、vfork

vfork函数的做法更加简单粗暴,内核连子进程的虚拟空间也不创建了,直接共享了父进程的虚拟空间,也就间接的共享了物理空间,保证子进程先运行,在它调用exec或exit之后父进程才可能被调度。

接下来呢还有一个问题就是父进程打开的文件指针位置在子进程里面是否一样?

5、已打开文件列表

父进程的打开文件指针存放在PCB中,PCB被复制到子进程中后,子进程对应相应的文件描述符也能对文件进行操作,该描述符指向同一个文件表项,文件表项引用计数加1;

打开文件的内核数据结构

两个独立进程各自打开同一个文件

注:此图中可以看出,对于同一个文件,打开该文件的每个进程都得到一个文件表项,但对一个给定的文件只有一个v节点表项。而每个进程都有自己的文件表项的一个理由是:使每个进程都有它自己的对该文件的当前偏移量。

注:
文件描述符标志的作用域:只在一个进程中
文件状态标志的作用域:任何进程中的所有描述符都可指向同一个文件状态标志。

父子进程的每一个相同的打开文件描述符共享一个文件表项

注:文件表项只有在所有引用它的fd(即文件描述符)全部关闭的情况下才会真正关闭,如果子进程关闭父、子进程共享的文件描述符后父进程仍可以使用对应的文件表项。

原文链接:https://blog.csdn.net/lm9140802/article/details/78577165

linux进程--fork详解(三)相关推荐

  1. linux进程--fork详解(二)

    一.fork入门知识 一个进程,包括代码.数据和分配给进程的资源.fork()函数通过系统调用创建一个与原来进程几乎完全相同的进程,也就是两个进程可以做完全相同的事,但如果初始参数或者传入的变量不同, ...

  2. (渗透测试后期)Linux进程隐藏详解

    文章目录 (渗透测试后期)Linux进程隐藏详解 前言 Linux进程基础 Linux进程侦查手段 Linux进程隐藏手段 一.基于用户态的进程隐藏 方法1:小隐隐于/proc/pid--劫持read ...

  3. Linux进程退出详解(do_exit)--Linux进程的管理与调度(十四)

    Linux进程的退出 linux下进程退出的方式 正常退出 从main函数返回return 调用exit 调用_exit 异常退出 调用abort 由信号终止 _exit, exit和_Exit的区别 ...

  4. linux 进程数据结构,Linux进程数据结构详解

    1.Linux的进程简介: 支持多线程的操作系统中,进程是资源分配的最小单位,线程是调度的基本单位.Linux是现代的32位或64位的支持多线程的操作系统,不过Linux是一种以轻量级进程作为线程,多 ...

  5. 【Linux】第八讲:Linux进程信号详解(一)_ 认识信号 | 产生信号

    「前言」文章是关于Linux进程信号方面的知识,本文的内容是Linux进程信号第一讲,讲解会比较细,下面开始! 「归属专栏」Linux系统编程 「笔者」枫叶先生(fy) 「座右铭」前行路上修真我 「枫 ...

  6. web linux进程管理,详解Supervisor安装与配置(Linux/Unix进程管理工具)

    Supervisor(http://supervisord.org/)是用Python开发的一个client/server服务,是Linux/Unix系统下的一个进程管理工具,不支持Windows系统 ...

  7. linux进程--exec详解(四)

    1.exec 系统调用exec是以新的进程去代替原来的进程,但进程的PID保持不变.因此,可以这样认为,exec系统调用并没有创建新的进程,只是替换了原来进程上下文的内容.原进程的代码段,数据段,堆栈 ...

  8. 奇小葩讲设备树(3/5)-- Linux设备树详解(三)u-boot设备树的传递

    前面两节介绍了设备的基本概念.编译.结构的组成,本章讨论的主要内容为 dtb如何通过Bootloader引导程序加载到内核 bootloader如何解析dbt bootloader支持哪些dtb的操作 ...

  9. linux设置共享权限设置命令,Linux系列知识详解(三)--------- Linux链接命令和权限管理命令...

    Linux系列知识详解(三)--------- Linux链接命令和权限管理命令 一:链接命令ln 简介:什么是链接命令?链接命令分为软链接和硬链接.其中软链接产生的新文件是以路径的形式表示原文件,类 ...

最新文章

  1. 用友Cell组件使用总结
  2. Openstack组建部署 — Glance Install
  3. LightOJ 1084 Winter(记忆化搜索)
  4. 机器学习问题总结(02)
  5. TCP通信过程大讨论
  6. Linux进程实践(3) --进程终止与exec函数族
  7. 设置本地yum源优先
  8. CF 917A The Monster 【括号匹配】
  9. Java - 多线程Callable、Executors、Future
  10. FPGA入门——初学建议
  11. html点击复制一段文字内容,js实现点击按钮复制文本功能
  12. 丹尼斯·里奇的自述简历
  13. UMLChina公众号文章精选(20220619更新精选)
  14. 树莓派查看CPU温度
  15. python如何读取dbf文件_python2.7读取dbf文件的正确姿势
  16. 伊甸园日历游戏(vijos--1004)
  17. 哈夫曼树+K叉哈夫曼树
  18. zzulioj 1029: 三角形判定
  19. 什么是商家转账到零钱
  20. Java AES加密工具类

热门文章

  1. 用python画爱心-python画一个玫瑰和一个爱心
  2. vscode使用教程python-硬核教程:五步掌握用VSCode进行高效Python开发
  3. python3下载文件-使用Python 3从网上下载文件
  4. 零基础是学java还是python-老男孩零基础学习|python和java那个更有发展前景?
  5. python创建一个txt文件-python新建txt文件,并逐行写入数据
  6. python在财务领域的应用-浅谈财务智能化在实际工作中的运用
  7. python中可以用中文作为变量-在Python 3.x中可以使用中文作为变量名。
  8. python语言基础-Python语言基础与应用
  9. python爬虫实例-python使用百度进行爬虫简单学习例子
  10. mybatis不使用动态代理查询时设计与实现