当前位置: 首页 > news >正文

【Linux】写时拷贝技术COW (copy-on-write)

文章目录

  • Linux写时拷贝技术(copy-on-write)
    • 进程的概念
      • 进程的定义
        • 进程和程序的区别
        • PCB的内部构成
    • 程序是如何被加载变成进程的?
      • 写时复制(Copy-On-Write, COW)
        • 写时复制机制的原理
        • 写时拷贝的场景
      • fork与COW
      • vfork与fork


Linux写时拷贝技术(copy-on-write)

在了解写时拷贝技术之前我们得先知道进程

进程的概念

进程的定义

肤浅的来说,加载到内存中的程序就叫做进程。但这并不完善。

运行中的系统存在大量的进程,操作系统该如何管理这些进程呢?仍然是先描述再组织。

进程在形成之初,操作系统就会为其创建进程控制块 PCB。进程控制块PCB用于描述进程,其中存储着进程的所有属性。

Linux 系统中,PCB 就是一个名为task_struct的结构体。

Linux 查看进程的命令:

$ ps axj | head -1 && ps axj | grep 'myproc'PPID   PID  PGID   SID TTY      TPGID STAT   UID   TIME COMMAND
25486 29733 29733 25486 pts/0    29733 S+    1003   0:00 ./myproc # 正在运行的myproc进程

启动程序的本质,就是在内存上创建进程。

进程和程序的区别
  • 程序本质就是文件,是编译生成的二进制可执行文件。
  • 程序被加载到内存中,系统自动为其创建PCB,以管理该进程。故进程是程序的代码数据与进程相关内核数据结构的总和

操作系统在处理进程时, 不是直接操作程序而是读写PCB,因为PCB中含有程序的所有属性。也就是说,进程管理与进程对应的程序毫无关系,只与进程的PCB强相关

PCB的内部构成

task_struct结构

  • 进程编号 —— 每个进程都有编号或称标识符,也就是 PID,具有唯一性用来区别于其他进程。
  • 进程状态 —— 包括进程退出时的退出码、退出信号、任务状态等。
#include <sys/types.h>
#include <unistd.h>
pid_t getpid(void);
pid_t getppid(void);

程序是如何被加载变成进程的?

首先,程序通过编译器转换为目标代码,并由链接器与库函数链接,形成可执行文件。此时程序内部已分配逻辑地址,但尚未映射至物理内存。当程序被执行时,操作系统将其从存储介质加载至内存,并进行逻辑地址到物理地址的映射,这一映射关系存储于页表中。

在C/C++中,地址并不是内存物理上的地址,而是操作系统提供的虚拟地址。操作系统不允许直接读取物理内存。虚拟地址在不同进程中是相同的,但物理地址是不同的。例如,当使用fork函数创建子进程时,父进程的栈空间中的变量并不会直接复制到子进程中,而是通过写时拷贝的机制。这意味着,当父进程或子进程尝试修改这些变量时,才会发生真正的复制操作,从而保证了父子进程间的数据独立性。

如果想要执行你书中(A程序)第8页的一段代码,那就由一个人,我们叫他管理员(操作系统),管理员把这一页程序复制到这本速读书(物理地址空间)的某个空白页上,比如第1页,同时记录这个映射关系(A程序的第8页放在了这本书的第1页),如果B程序也要执行第8页中的一段代码(虚拟地址相同),也需要由那个人把这一页复制到这本速读书的某个空白页上,比如第二页,并将映射关系记录在映射表上。这种情况就是虚拟地址相同,但被放在了不同的物理地址上。

在这里插入图片描述

写时复制(Copy-On-Write, COW)

写时复制(Copy-on-Write, COW)是一种优化策略。其主要思想是,当多个调用者(callers)请求相同资源(如内存或磁盘上的数据存储)时,他们会共享相同的指针指向同一资源。只有当某个调用者尝试修改资源内容时,系统才会为该调用者创建一份专用副本(private copy)。这种策略对其他调用者是透明的,只有在修改资源时才会创建副本,因此在调用者仅进行读取操作时可以共享同一份资源。

写时复制机制的原理

进程具有独立性,为了保证进程间数据独立,进程间不相互干扰,会有数据的写时拷贝,得到一张新的页表。在上面的程序中,变量的物理地址实际就不同了,因此数据也是不同的。

img

写时拷贝技术实际上是运用了一个 “引用计数” 的概念来实现的。在开辟的空间中多维护四个字节来存储引用计数。
有两种方法:

  • 多开辟四个字节(pCount)的空间,用来记录有多少个指针指向这片空间。
  • 在开辟空间的头部预留四个字节的空间来记录有多少个指针指向这片空间。

当我们多开辟一份空间时,让引用计数+1,如果有释放空间,那就让计数-1,但是此时不是真正的释放,是假释放,等到引用计数变为 0 时,才会真正的释放空间。如果有修改或写的操作,那么也让原空间的引用计数-1,并且真正开辟新的空间。

linux 下的 fork() 就是用的写时拷贝技术,引用计数不光在 string 这里用到,还有智能指针 shared_ptr 也用到了引用计数来解决拷贝问题。

写时拷贝的场景

虚拟内存管理中的写时复制

  • 在虚拟内存管理中,页面通常被标记为只读。当某个进程尝试向内存写入数据时,内存管理单元(MMU)会抛出一个异常。内核在处理该异常时,会为该进程分配一份新的物理内存并复制数据到该内存中,然后重新执行写操作。

数据存储中的写时复制

  • Linux等操作系统的文件管理系统使用了写时复制策略。
  • 数据库服务器也通常采用写时复制策略,为用户提供快照(snapshot)。

软件应用中的写时复制

  • C++标准程序库中的std::string类,在C++98/C++03标准中允许写时复制策略,但在C++11标准中为了提高并行性取消了这一策略。GCC从版本5开始,std::string不再采用COW策略。

fork与COW

fork是Linux系统中用于创建新进程的系统调用。在传统的fork实现中,子进程会完全复制父进程的地址空间,包括数据段、堆、栈和只读的代码段。这种复制操作可能会消耗大量的时间和内存资源。

为了优化这一过程,现代操作系统引入了写时复制(Copy-On-Write, COW)策略。在fork之后,子进程和父进程共享数据段、堆和代码段,但内核会将这些共享区域的访问权限设置为只读。如果任何一个进程尝试修改这些共享区域,内核会为该进程创建该区域的一个私有副本,这个过程称为“写时复制”。这样,只有在实际需要修改数据时,才会发生内存复制,从而节省了内存空间和复制时间。

vfork与fork

vfork是另一种用于创建新进程的系统调用,它与fork的主要区别在于,vfork不会复制父进程的地址空间,而是让子进程直接在父进程的地址空间中运行,直到子进程调用execexit。这意味着子进程在调用execexit之前,对父进程地址空间中的任何修改都会影响到父进程。

vfork的设计初衷是为了在子进程立即调用exec执行新程序的情况下,避免不必要的地址空间复制。由于子进程不会访问父进程的地址空间,因此vfork可以更高效地创建新进程。

然而,vfork的使用需要非常小心,因为子进程和父进程共享地址空间,这可能导致数据竞争和不确定的行为。因此,vfork通常在子进程调用execexit后立即返回,以避免潜在的问题。

vfork与fork的对比

  • fork通过写时复制技术优化了进程创建过程,允许父进程和子进程共享地址空间,直到需要修改时才进行复制。
  • vfork则是在子进程立即调用execexit的情况下,避免复制父进程的地址空间,直接在父进程的地址空间中运行子进程。

两者都是创建新进程的方法,但fork更为通用,而vfork则是在特定场景下的一种优化手段。由于vfork可能带来的风险,现代操作系统中fork通常已经足够高效,而vfork的使用则越来越少。

相关文章:

【Linux】写时拷贝技术COW (copy-on-write)

文章目录 Linux写时拷贝技术(copy-on-write)进程的概念进程的定义进程和程序的区别PCB的内部构成 程序是如何被加载变成进程的&#xff1f;写时复制&#xff08;Copy-On-Write, COW&#xff09;写时复制机制的原理写时拷贝的场景 fork与COWvfork与fork Linux写时拷贝技术(copy-…...

用python使用主成分分析数据

import pandas as pd #导入处理二维表格的库 import numpy as np #导入数值计算的库 from sklearn.preprocessing import StandardScaler #导入数据标准化模块 import matplotlib.pyplot as plt #导入画图的包 from sklearn.decomposition import PCA #导入主成…...

用WPS将多张图片生成一个pdf文档,注意参数设置

目录 1 新建一个docx格式的文档 2 向文档中插入图片 3 设置页边距 4 设置图片大小 5 导出为pdf格式 需要把十几张图片合并为一个pdf文件&#xff0c;本以为很简单&#xff0c;迅速从网上找到两个号称免费的在线工具&#xff0c;结果浪费了好几分钟时间&#xff0c;发现需要…...

virtual box ubuntu20 全屏展示

virtual box 虚拟机 ubuntu20 系统 全屏展示 ubuntu20.04 视图-自动调整窗口大小 视图-自动调整显示尺寸 系统黑屏解决 ##设备-安装增强功能 ##进入终端 ##终端打不开&#xff0c;解决方案-传送门ubuntu Open in Terminal打不开终端解决方案-CSDN博客 ##点击cd盘按钮进入文…...

react中的数据驱动视图,useState()的使用

前端开发如今有一个很重要的思想就是数据驱动视图&#xff0c;数据发生变化使ui发生变化&#xff0c;比如一个变量count&#xff0c;为0显示三个按钮&#xff0c;为1显示一个按钮&#xff0c;为2显示两个按钮。这就是一个简单的数据驱动视图。 import { useState } from reactf…...

金融数据库,实时行情,股票财务数据在线查询

jvQuant在线SQL 文档(current)接入 测试 查询 #股票代码股票简称最新价(元)2024-05-21股东总户数(户)截至2024-05-21上市板块是否ST股票区间涨跌幅(%)2024-05-15-2024-05-21市盈率(TTM)(倍)2024-05-21营业收入(元)截至2024-03-31总市值(元)2024-05-21量比2024-05-21利润率(%…...

开源模型应用落地-LangSmith试炼-入门初体验-数据集评估(三)

一、前言 LangSmith是一个用于构建生产级 LLM 应用程序的平台&#xff0c;它提供了调试、测试、评估和监控基于任何 LLM 框架构建的链和智能代理的功能&#xff0c;并能与LangChain无缝集成。通过使用LangSmith帮助开发者深入了解模型在不同场景下的表现&#xff0c;让开发者能…...

设计模式 15 Decorator Pattern 装饰器模式

设计模式 15 Decorator Pattern 装饰器模式 1.定义 Decorator Pattern 装饰器模式是一种结构型设计模式&#xff0c;它允许在运行时给对象添加新的行为或职责&#xff0c;而无需修改对象的源代码。这种模式通过创建一个包装对象&#xff0c;也称为装饰器&#xff0c;来包裹原…...

cuda11.8安装torch2.0.1

pip install torch2.0.1 torchvision0.15.2 torchaudio2.0.2 --index-url https://download.pytorch.org/whl/cu118...

新手困 ViewModel与Activting的databinding2个对象 区别

在Android开发中&#xff0c;ViewModel与Activity的Binding并不是同一个概念&#xff0c;它们分别指的是不同的功能和用途。 ViewModel: ViewModel是一个为UI界面提供数据的类&#xff0c;它负责管理Activity或Fragment的数据。ViewModel类持有数据的引用&#xff0c;即使配置…...

Cocos Creator 声音播放与管理详解

Cocos Creator 是一款非常流行的游戏开发引擎&#xff0c;它提供了丰富的功能和工具&#xff0c;让开发者可以轻松构建出高质量的游戏。在游戏开发中&#xff0c;声音是一个非常重要的元素&#xff0c;可以为游戏增添氛围和趣味性。在本文中&#xff0c;我们将详细介绍Cocos Cr…...

今日早报 每日精选15条新闻简报 每天一分钟 知晓天下事 5月26日,星期日

每天一分钟&#xff0c;知晓天下事&#xff01; 2024年5月26日 星期日 农历四月十九 1、 医保局&#xff1a;支持将符合条件的村卫生室纳入医保定点&#xff0c;方便农村居民就医。 2、 网传养老金储备严重不足&#xff1f;央视辟谣&#xff1a;这笔钱二十多年来从未动用过&a…...

IDEA快速生成类注释和方法注释的方法

1.生成类、接口、枚举、注解等文件的注释&#xff0c;不仅仅是class 2.生成方法注释的 可在方法上方空行输入/** 按enter键快速生成。生成的样式如下&#xff1a; PS:生成的返回值带一堆英文文字说明&#xff0c;感觉没必要 如果想生成比较全面的方法注释&#xff0c;如作者&…...

[集群聊天服务器]----(七)业务模块之一对一聊天、添加好友函数、好友类以及离线消息类

接着[集群聊天服务器]----(六)业务模块之用户注册、登录、退出以及客户端异常退出函数中对于业务模块的用户注册、登录、退出以及客户端异常退出函数的剖析&#xff0c;现在我们对点对点聊天以及添加好友的实现进行剖析。 点对点聊天 当客户端输入msgidONE_CHAT_MSG时&#x…...

java中使用jedis连接redis

4.java中使用jedis连接redis...

【多线程开发 2】从代码到实战TransmittableThreadLocal

【多线程开发 2】从代码到实战TransmittableThreadLocal 本文将从以下几个点讲解TransmittableThreadLocal(为了方便写以下简称ttl)&#xff1a; 前身 是什么&#xff1f; 可以用来做什么&#xff1f; 源码原理 实战 前身 ThreadLocal 要了解ttl就要先了解Java自带的类…...

【车载以太网测试从入门到精通】——SOME/IP协议测试

系列文章目录 【车载以太网测试从入门到精通】系列文章目录汇总 文章目录 系列文章目录前言一、SOME/IP时间参数1.INITIAL_DELAY时间2.REPETITIONS_MAX次数3.REPETITIONS_BASE_DELAY时间4.CYCLIC_OFFER_DELAY时间5.TIME_TO_LIVE时间6.SUBSCRIBE_RETRY_DELAY时间二、SOME/IP服务…...

作业39 sqrt应用

目录 判断完全平方数 题目描述 输出所有因数 题目描述 因子求和 题目描述 判断素数 题目描述 判断完全平方数 题目描述 输入一个整数&#xff0c;判断他是否是完全平方数&#xff0c;如果是&#xff0c;输出yes&#xff0c;否则输出no 样例 样例…...

springboot 实现跨域的几种方式

1、跨域的原因&#xff1a; 由于同源策略(Same Origin Policy)的限制,浏览器不允许跨域请求。同源策略规定,A网页设置的Cookie、LocalStorage和IndexDB无法被同源以外的网页读取。 2、原因&#xff1a; 1&#xff09;浏览器的同源策略(Same Origin Policy)限制了跨域请求。主要…...

springmvc Web上下文初始化

Web上下文初始化 web上下文与SerlvetContext的生命周期应该是相同的&#xff0c;springmvc中的web上下文初始化是由ContextLoaderListener来启动的 web上下文初始化流程 在web.xml中配置ContextLoaderListener <listener> <listener-class>org.springframework.…...

深度学习在微纳光子学中的应用

深度学习在微纳光子学中的主要应用方向 深度学习与微纳光子学的结合主要集中在以下几个方向&#xff1a; 逆向设计 通过神经网络快速预测微纳结构的光学响应&#xff0c;替代传统耗时的数值模拟方法。例如设计超表面、光子晶体等结构。 特征提取与优化 从复杂的光学数据中自…...

利用ngx_stream_return_module构建简易 TCP/UDP 响应网关

一、模块概述 ngx_stream_return_module 提供了一个极简的指令&#xff1a; return <value>;在收到客户端连接后&#xff0c;立即将 <value> 写回并关闭连接。<value> 支持内嵌文本和内置变量&#xff08;如 $time_iso8601、$remote_addr 等&#xff09;&a…...

智慧工地云平台源码,基于微服务架构+Java+Spring Cloud +UniApp +MySql

智慧工地管理云平台系统&#xff0c;智慧工地全套源码&#xff0c;java版智慧工地源码&#xff0c;支持PC端、大屏端、移动端。 智慧工地聚焦建筑行业的市场需求&#xff0c;提供“平台网络终端”的整体解决方案&#xff0c;提供劳务管理、视频管理、智能监测、绿色施工、安全管…...

Cloudflare 从 Nginx 到 Pingora:性能、效率与安全的全面升级

在互联网的快速发展中&#xff0c;高性能、高效率和高安全性的网络服务成为了各大互联网基础设施提供商的核心追求。Cloudflare 作为全球领先的互联网安全和基础设施公司&#xff0c;近期做出了一个重大技术决策&#xff1a;弃用长期使用的 Nginx&#xff0c;转而采用其内部开发…...

04-初识css

一、css样式引入 1.1.内部样式 <div style"width: 100px;"></div>1.2.外部样式 1.2.1.外部样式1 <style>.aa {width: 100px;} </style> <div class"aa"></div>1.2.2.外部样式2 <!-- rel内表面引入的是style样…...

06 Deep learning神经网络编程基础 激活函数 --吴恩达

深度学习激活函数详解 一、核心作用 引入非线性:使神经网络可学习复杂模式控制输出范围:如Sigmoid将输出限制在(0,1)梯度传递:影响反向传播的稳定性二、常见类型及数学表达 Sigmoid σ ( x ) = 1 1 +...

图表类系列各种样式PPT模版分享

图标图表系列PPT模版&#xff0c;柱状图PPT模版&#xff0c;线状图PPT模版&#xff0c;折线图PPT模版&#xff0c;饼状图PPT模版&#xff0c;雷达图PPT模版&#xff0c;树状图PPT模版 图表类系列各种样式PPT模版分享&#xff1a;图表系列PPT模板https://pan.quark.cn/s/20d40aa…...

Mac下Android Studio扫描根目录卡死问题记录

环境信息 操作系统: macOS 15.5 (Apple M2芯片)Android Studio版本: Meerkat Feature Drop | 2024.3.2 Patch 1 (Build #AI-243.26053.27.2432.13536105, 2025年5月22日构建) 问题现象 在项目开发过程中&#xff0c;提示一个依赖外部头文件的cpp源文件需要同步&#xff0c;点…...

Xen Server服务器释放磁盘空间

disk.sh #!/bin/bashcd /run/sr-mount/e54f0646-ae11-0457-b64f-eba4673b824c # 全部虚拟机物理磁盘文件存储 a$(ls -l | awk {print $NF} | cut -d. -f1) # 使用中的虚拟机物理磁盘文件 b$(xe vm-disk-list --multiple | grep uuid | awk {print $NF})printf "%s\n"…...

智能AI电话机器人系统的识别能力现状与发展水平

一、引言 随着人工智能技术的飞速发展&#xff0c;AI电话机器人系统已经从简单的自动应答工具演变为具备复杂交互能力的智能助手。这类系统结合了语音识别、自然语言处理、情感计算和机器学习等多项前沿技术&#xff0c;在客户服务、营销推广、信息查询等领域发挥着越来越重要…...