• 关于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)线程间的栈的是独占的,堆共享;而进程间的话堆栈都是独立的,当然,比较进程的意义就不太大了,因为进程间本来就是独立的个体。

  • 相关阅读:
    线程应用实例
    电脑安装了ubnutu20.04双系统以后,卡死在grub界面里
    GD32(7)程序烧录及运行
    使用C语言实现并查集
    Vue前端添加水印功能
    合肥先进光源束测专用网络的规划-续
    Java多并发(二)| cas & synchronized & volatile的内存语义
    奥拉帕尼人血清白蛋白HSA纳米粒|陶扎色替卵清白蛋白OVA纳米粒|来他替尼小鼠血清白蛋白MSA纳米粒(试剂)
    腾讯云学生专享云服务器介绍及购买攻略
    HCIA回顾笔记
  • 原文地址:https://blog.csdn.net/qq_52563729/article/details/125883337