• 关于fork的一些知识


    什么是fork

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

    2.一个进程调用fork()函数后,系统先给新的进程分配资源,例如存储数据和代码的空间。然后把原来的进程的所有值都复制到新的新进程中,只有少数值与原来的进程的值不同。相当于克隆了一个自己。

    3.fork调用的一个奇妙之处就是它仅仅被调用一次,却能够返回两次,它可能有三种不同的返回值:
    1)在父进程中,fork返回新创建子进程的进程ID;
    2)在子进程中,fork返回0;
    3)如果出现错误,fork返回一个负值

    读时共享,写是复制

    1 fork之后,父子进程共享哪些内容
    很实际上刚fork之后:
    1)父子进程相同之处:
    全局变量、.data、.text、栈、堆、环境变量、用户ID、宿主目录、进程工作目录、信号处理方式…
    2)父子不同处:
    1.进程ID
    2.fork返回值
    3.父进程ID
    4.进程运行时间
    5.闹钟(定时器)
    6.未决信号集。

    分析:
    1)用户区:
    在相同之处中只有宿主和进程工作目录是位于PCB的,其余都是位于3G用户区的虚拟内存,这样看似乎子进程将3G的内存都拷贝了一份,但这是真的吗?
    为了防止这样的拷贝浪费内存,设计者想出了父子进程“读时共享,写时复制”。注意是父子进程,写的时候都会拷贝。
    也就是说刚fork之后用户区的东西可以认为是共享的,但是当你父进程或者子进程进行写操作的时候,它们都会各自拷贝一份进行修改,而不对原来父进程的数据直接操作,所以写时是不共享的。后面的例子会证明到。

    2)内核区:
    而内核区实际上基本都是不共享的,例如进程ID这些;部分存在读时共享写时复制例如进程当前工作目录;共享的只有文件描述符和mmap建立的影视区。我们只需要记住最后内核区共享的两点即可。

    总结1:
    1)我们只需要记住: 线程间共享全局变量,而进程间读时共享,写时复制。更详细的说:线程共享堆和全局区(即共享数据段、代码段等地址空间),常用的是全局变量。而进程不共享全局变量,只能借助mmap。

    2)内核区只共享文件描述符和mmap映射区。

    3)线程间的栈的是独占的,堆共享;而进程间的话堆栈都是独立的,当然,比较进程的意义就不太大了,因为进程间本来就是独立的个体。

  • 相关阅读:
    zookeeper
    肝了两周,一张图解锁Spring核心源码
    c程序从编译开始到运行结束的过程
    FRED应用:TMT MOBIE成像光谱仪的概念设计阶段杂散光分析
    C++单例模式与工厂模式
    例39:使用List控件
    嵌入式中I2C 相关的硬件问题汇总及死锁解决办法
    uniapp打包微信小程序。报错:https://api.weixin.qq.com 不在以下 request 合法域名列表
    基于FPGA的远程升级系统概述
    【毕业设计】31-基于单片机的农业蔬菜大棚温度自动控制系统设计(原理图工程+源码工程+仿真工程+答辩论文+答辩PPT)
  • 原文地址:https://blog.csdn.net/qq_52563729/article/details/125883337