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

  • 相关阅读:
    Java注解
    《剑指Offer》刷题之打印从1到最大的n位数
    【Axure教程】将figma导入Axure
    Learning from Unlabeled 3D Environments forVision-and-Language Navigation
    如何比较两个或多个分布:从可视化到统计检验的方法总结
    奇妙的跨域错误-Access-Control-Request-Private-Network
    【笔试实战】LeetCode题单刷题-编程基础 0 到 1【一】
    windows server安装mysql后公司区域网连接
    QCC51XX---GATT
    Java常量与变量
  • 原文地址:https://blog.csdn.net/qq_52563729/article/details/125883337