写时复制(COW)详解

2023-11-09 18:10
文章标签 详解 cow 复制 写时

本文主要是介绍写时复制(COW)详解,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

1、写时复制简介

写时复制Copy-on-write,简称COW)是一种计算机程序设计领域的优化策略。其核心思想是,如果有多个调用者(callers)同时请求相同资源(如内存或磁盘上的数据存储),他们会共同获取相同的指针指向相同的资源,直到某个调用者试图修改资源的内容时,系统才会真正复制一份专用副本(private copy)给该调用者,而其他调用者所见到的最初的资源仍然保持不变。这过程对其他的调用者都是透明的。此作法主要的优点是如果调用者没有修改该资源,就不会有副本(private copy)被创建,因此多个调用者只是读取操作时可以共享同一份资源。

2、用途:

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

一般把这种被共享访问的页面标记为只读。当一个task试图向内存中写入数据时,内存管理单元(MMU)抛出一个异常,内核处理该异常时为该task分配一份物理内存并复制数据到此内存,重新向MMU发出执行该task的写操作。

数据存储中的写时复制

Linux等的文件管理系统使用了写时复制策略。

数据库服务器也一般采用了写时复制策略,为用户提供一份snapshot。

软件应用中的写时复制

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

3、写时复制详解

COW是存储系统中使用的基本更新策略之一(还有就地更新(UIP))。基本模式永远不会覆盖旧数据。使用COW策略更新数据块时,数据块被读入内存,进行修改,然后写入新位置,而旧数据则保持不变。由于COW永远不会覆盖旧数据,因此通常用于防止由于本地文件系统中的系统崩溃而导致数据丢失,COW更新策略已在存储系统中广泛使用

但是COW引入了令人不愉快的递归更新过程。文件系统可以看作是由磁盘块组成的大树,当使用COW策略修改叶块时,还需要修改其父节点以更新修改后的子块的新位置。此更新过程将递归进行,直到到达根块为止,该根块可以在磁盘上的固定位置进行更新。我们将这样的过程定义为递归更新。递归更新可能会导致存储系统出现多种副作用,例如WRITE放大,I / O模式变更和性能下降

缺点:

  1. 放大:递归更新可能会导致写放大,比如应用程序只需要修改一个叶子数据块F 但是,递归更新导致总共修改了四个父级节点(F->D->A->Root)。实际刷新的数据高达4 × 请求的数据。实际上,由于在这种情况下忽略了由块分配引起的递归更新,因此修改的块数量可能会更高。
  2. 性能下降 WRITE放大会引入其他数据以进行写入,这最终可能会降低文件系统的性能。

优点:

  1. 保护数据:本地文件系统.由于有备份机制,不会因为文件系统崩溃导致大量甚至全部数据丢失.
  2. 提高性能:日志结构的文件系统,例如Sprite LFS,使用COW更新策略将访问模式从大量的小随机写入转换为单个大的顺序WRITE,从而利用了磁盘顺序I / O带来的高性能。
  3. 在特殊介质上更新数据:一次写入多次读取的介质,例如光盘,使用COW实施随机WRITE。闪存文件系统使用COW优化更新过程,这有助于提高WRITE性能并实现损耗均衡。

4、fork和cow

cow是一种优化策略,fork是linux提供的创建新线程的方法,大多数的fork实现借用了cow策略来节省内存空间.

子进程和父进程继续执行fork之后的指令。子进程是父进程的复制品。例如,子进程获得
父进程数据空间、堆和栈的复制品。注意,这是子进程所拥有的拷贝。父、子进程并不共享这
些存储空间部分。如果正文段是只读的,则父、子进程共享正文段 ,
现在很多的实现并不做一个父进程数据段和堆的完全拷贝,因为在fork之后经常跟随着

exec。作为替代,使用了在写时复制技术。这些区域由父、子进程共

享,而且内核将它们的存取许可权改变为只读的。如果有进程试图修改这些区域,则内核为有
关部分,典型的是虚存系统中的“页” .

fork细节:一般来说,在fork之后是父进程先执行还是子进程先执行是不确定的。这取决于内核所使用的

调度算法。如果要求父、子进程之间相互同步,则要求某种形式的进程间通信

总结:所以在使用fork在借用cow策略实现时,其实父子进程会共享数据段、代码段、堆,而栈是父子进程独有的.

5、vfork和fork

vfork也用于创建一个新进程,而该新进程的目的是调用exec执行一个新程序。但vfork它并不将父进程的地址空间完全复制到子进程中,因为子进程会立即调用 exec(exit),于

是也就不会存访该地址空间。不过在子进程调用 exec或exit之前,它在父进程的空间中运行。
这种工作方式在某些 U N I X的页式虚存实现中提高了效率(和fork类似即:在fork之后跟随
exec,并采用在写时复制技术相类似) 。
vfork和fork之间的另一个区别是:vfork保证子进程先运行,在它调用exec或exit之后父进
程才可能被调度运行。 (如果在调用这两个函数之前子进程依赖于父进程的进一步动作,则会
导致死锁。子进程在exec和exit之前其实运行在父进程的内存空间,所以子进程的数据操作其实是在修改父进程的对应数据.操作不当有可能导致进程崩溃.所以vfork之后建议立即执行exec或exit

tips:UIP是将目标块读入内存,进行修改,然后在其原始位置写入磁盘(覆盖旧数据)

引用:
1.https://en.wikipedia.org/wiki/Copy-on-write

2.https://ieeexplore.ieee.org/abstract/document/6879362/similar#similar

3.《unix环境高级编程第8章》

 干货将在我的微信公众号:小梁编程汇 持续更新。喜欢的话可以关注我微信公众哦
                                在这里插入图片描述

这篇关于写时复制(COW)详解的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/377756

相关文章

Linux线程同步/互斥过程详解

《Linux线程同步/互斥过程详解》文章讲解多线程并发访问导致竞态条件,需通过互斥锁、原子操作和条件变量实现线程安全与同步,分析死锁条件及避免方法,并介绍RAII封装技术提升资源管理效率... 目录01. 资源共享问题1.1 多线程并发访问1.2 临界区与临界资源1.3 锁的引入02. 多线程案例2.1 为

Python使用Tenacity一行代码实现自动重试详解

《Python使用Tenacity一行代码实现自动重试详解》tenacity是一个专为Python设计的通用重试库,它的核心理念就是用简单、清晰的方式,为任何可能失败的操作添加重试能力,下面我们就来看... 目录一切始于一个简单的 API 调用Tenacity 入门:一行代码实现优雅重试精细控制:让重试按我

Python标准库之数据压缩和存档的应用详解

《Python标准库之数据压缩和存档的应用详解》在数据处理与存储领域,压缩和存档是提升效率的关键技术,Python标准库提供了一套完整的工具链,下面小编就来和大家简单介绍一下吧... 目录一、核心模块架构与设计哲学二、关键模块深度解析1.tarfile:专业级归档工具2.zipfile:跨平台归档首选3.

idea的终端(Terminal)cmd的命令换成linux的命令详解

《idea的终端(Terminal)cmd的命令换成linux的命令详解》本文介绍IDEA配置Git的步骤:安装Git、修改终端设置并重启IDEA,强调顺序,作为个人经验分享,希望提供参考并支持脚本之... 目录一编程、设置前二、前置条件三、android设置四、设置后总结一、php设置前二、前置条件

python中列表应用和扩展性实用详解

《python中列表应用和扩展性实用详解》文章介绍了Python列表的核心特性:有序数据集合,用[]定义,元素类型可不同,支持迭代、循环、切片,可执行增删改查、排序、推导式及嵌套操作,是常用的数据处理... 目录1、列表定义2、格式3、列表是可迭代对象4、列表的常见操作总结1、列表定义是处理一组有序项目的

python使用try函数详解

《python使用try函数详解》Pythontry语句用于异常处理,支持捕获特定/多种异常、else/final子句确保资源释放,结合with语句自动清理,可自定义异常及嵌套结构,灵活应对错误场景... 目录try 函数的基本语法捕获特定异常捕获多个异常使用 else 子句使用 finally 子句捕获所

C++11范围for初始化列表auto decltype详解

《C++11范围for初始化列表autodecltype详解》C++11引入auto类型推导、decltype类型推断、统一列表初始化、范围for循环及智能指针,提升代码简洁性、类型安全与资源管理效... 目录C++11新特性1. 自动类型推导auto1.1 基本语法2. decltype3. 列表初始化3

SQL Server 中的 WITH (NOLOCK) 示例详解

《SQLServer中的WITH(NOLOCK)示例详解》SQLServer中的WITH(NOLOCK)是一种表提示,等同于READUNCOMMITTED隔离级别,允许查询在不获取共享锁的情... 目录SQL Server 中的 WITH (NOLOCK) 详解一、WITH (NOLOCK) 的本质二、工作

springboot自定义注解RateLimiter限流注解技术文档详解

《springboot自定义注解RateLimiter限流注解技术文档详解》文章介绍了限流技术的概念、作用及实现方式,通过SpringAOP拦截方法、缓存存储计数器,结合注解、枚举、异常类等核心组件,... 目录什么是限流系统架构核心组件详解1. 限流注解 (@RateLimiter)2. 限流类型枚举 (

Java Thread中join方法使用举例详解

《JavaThread中join方法使用举例详解》JavaThread中join()方法主要是让调用改方法的thread完成run方法里面的东西后,在执行join()方法后面的代码,这篇文章主要介绍... 目录前言1.join()方法的定义和作用2.join()方法的三个重载版本3.join()方法的工作原