最简单的制作网站46云虚拟主机

diannao/2025/10/13 12:00:20/文章来源:
最简单的制作网站,46云虚拟主机,wordpress 订阅号推送,中小企业做网站贷款设计模式专栏#xff1a;http://t.csdnimg.cn/4j9Cq 目录 1.简介 2.实现原理 3.QString的实现分析 3.1.内部结构 3.2.写入时复制 4.示例分析 5.使用场景 6.总结 1.简介 CopyOnWrite (COW) 是一种编程思想#xff0c;用于优化内存使用和提高性能。COW 的基本思想是http://t.csdnimg.cn/4j9Cq 目录 1.简介 2.实现原理 3.QString的实现分析 3.1.内部结构 3.2.写入时复制 4.示例分析 5.使用场景 6.总结 1.简介 CopyOnWrite (COW) 是一种编程思想用于优化内存使用和提高性能。COW 的基本思想是如果多个对象或变量共享相同的数据那么它们最初可以共享同一份数据而不是为每个对象创建独立的数据副本。如果任何一个对象想要修改数据就会创建数据的副本然后在副本上进行修改而原始数据保持不变。 这种技术在处理不可变数据结构或很少修改数据的情况下特别有用。通过最初共享数据COW 避免了不必要的复制提高了内存效率。它还减少了对共享数据的修改对其他对象的影响因为它们继续引用原始数据直到进行修改。 Qt 的 QString 正是采用了 COW 思想它是如何工作的呢简单来说就是平时查询的时候都不需要加锁随便访问只有在更新的时候才会从原来的数据复制一个副本出来然后修改这个副本最后把原数据替换成当前的副本。修改操作的同时读操作不会被阻塞而是继续读取旧的数据。 2.实现原理 写时复制的原理就是浅拷贝加引用计数。 当只是进行读操作时就进行浅拷贝如果需要进行写操作的时候再进行深拷贝再加一个引用计数多个指针指向同一块空间记录同一块空间的对象个数。 1) QString之写时复制 当两个QString发生复制或者赋值时不会复制字符串内容而是增加一个引用计数然后字符串指针进行浅拷贝其执行效率为O(1)。只有当修改其中一个字符串内容时才执行真正的复制。 2) 引用计数 堆区为了好获取将将引用计数与数据放在一起并且最好在数据前面这样当数据变化的时候不会移动引用计数的位置 3.QString的实现分析 3.1.内部结构 QString 内部的数据结构是 QTypedArrayData template class T struct QTypedArrayData: QArrayData {... };typedef QTypedArrayDataushort QStringData;class Q_CORE_EXPORT QString { public:typedef QStringData Data;...Data* d; //真正存储QString数据的对象 }; 而 QTypedArrayData 继承自 QArrayData。 struct Q_CORE_EXPORT QArrayData {QtPrivate::RefCount ref; //引用计数int size;uint alloc : 31;uint capacityReserved : 1;qptrdiff offset; // in bytes from beginning of headervoid *data(){Q_ASSERT(size 0|| offset 0 || size_t(offset) sizeof(QArrayData));return reinterpret_castchar *(this) offset;}const void *data() const{Q_ASSERT(size 0|| offset 0 || size_t(offset) sizeof(QArrayData));return reinterpret_castconst char *(this) offset;}... }; QArrayData 有个 QtPrivate::RefCount 类型的成员变量 ref该成员变量记录着该内存块的引用。也就是说QString 采用了 Copy On Write 的技术优化了存放字符串的内存块。 3.2.写入时复制 QtPrivate::RefCount的作用就是保存计数从它的源码可以看出 class RefCount { public:inline bool ref() Q_DECL_NOTHROW { //增加引用计数int count atomic.load(); #if !defined(QT_NO_UNSHARABLE_CONTAINERS)if (count 0) // !isSharablereturn false; #endifif (count ! -1) // !isStaticatomic.ref();return true;}inline bool deref() Q_DECL_NOTHROW { //减少引用计数int count atomic.load(); #if !defined(QT_NO_UNSHARABLE_CONTAINERS)if (count 0) // !isSharablereturn false; #endifif (count -1) // isStaticreturn true;return atomic.deref();}...QBasicAtomicInt atomic; //原子变量 };在QString::QString(const QString other)复制构造函数中 QString QString::operator(const QString other) Q_DECL_NOTHROW {other.d-ref.ref(); //other增加引用计数 [1]if (!d-ref.deref()) //自己减少引用计数 [2]Data::deallocate(d); //如果自己计数为0则释放内存 [3]d other.d; //直接指针赋值 [4]return *this; } 通过4步完成了拷贝构造函数相比深拷贝 class String{ public:String(const String rhs):m_pstr(new char[strlen(rhs) 1]()){} private:char* m_pstr; }; 减少了内存申请和拷贝的过程从而大大的提高了运行效率。 在追加内容函数QString::append(const QString str) 的实现也看出的确是采用了 COW 技术 QString QString::append(const QString str) {if (str.d ! Data::sharedNull()) {if (d Data::sharedNull()) {operator(str);} else {if (d-ref.isShared() || uint(d-size str.d-size) 1u d-alloc)reallocData(uint(d-size str.d-size) 1u, true); //memcpy(d-data() d-size, str.d-data(), str.d-size * sizeof(QChar));d-size str.d-size;d-data()[d-size] \0;}}return *this; } void QString::reallocData(uint alloc, bool grow) {auto allocOptions d-detachFlags();if (grow)allocOptions | QArrayData::Grow;if (d-ref.isShared() || IS_RAW_DATA(d)) {Data *x Data::allocate(alloc, allocOptions);Q_CHECK_PTR(x);x-size qMin(int(alloc) - 1, d-size);::memcpy(x-data(), d-data(), x-size * sizeof(QChar));x-data()[x-size] 0;if (!d-ref.deref())Data::deallocate(d);d x;} else {Data *p Data::reallocateUnaligned(d, alloc, allocOptions);Q_CHECK_PTR(p);d p;} } 从上述代码可以看出reallocData函数在重新写入数据时会重新分配内存在新的内存上增加计数并减少原有内存技术这正是COW的思想所在。 4.示例分析 在C中虽然标准库并没有直接提供写入时复制的实现但你可以通过自定义数据结构来实现这种策略。下面是一个简单的示例展示了如何在C中实现一个写入时复制的数组 #include iostream #include vector #include memory template typename T class CopyOnWriteArray { private: std::shared_ptrstd::vectorT data; public: CopyOnWriteArray() : data(std::make_sharedstd::vectorT()) {} // 获取数组的大小 size_t size() const { return data-size(); } // 获取指定位置的元素只读 const T operator[](size_t index) const { return (*data)[index]; } // 修改指定位置的元素写入时复制 void set(size_t index, const T value) { if (data.unique()) { // 如果当前是唯一持有者则无需复制 } else { // 否则创建一个新的数据副本 data std::make_sharedstd::vectorT(*data); } (*data)[index] value; } // 添加一个新元素到数组的末尾写入时复制 void push_back(const T value) { if (data.unique()) { // 如果当前是唯一持有者则直接在原数组上添加元素 data-push_back(value); } else { // 否则创建一个新的数据副本并在副本上添加元素 data std::make_sharedstd::vectorT(*data); data-push_back(value); } } }; int main() { CopyOnWriteArrayint array; array.push_back(1); array.push_back(2); array.push_back(3); std::cout Size: array.size() std::endl; std::cout Element at index 1: array[1] std::endl; array.set(1, 100); // 写入时复制发生在这里 std::cout Element at index 1 after modification: array[1] std::endl; return 0; } 这个示例中CopyOnWriteArray 类使用 std::shared_ptr 来管理底层数据的生命周期。当多个 CopyOnWriteArray 对象共享同一个 std::vector 时如果其中一个对象尝试修改数据就会触发写入时复制。这是因为修改操作会检查 std::shared_ptr 的引用计数如果计数大于1就创建一个新的 std::vector 副本并在副本上进行修改。这样其他仍然引用原始 std::vector 的对象不会受到影响。 5.使用场景 写入时复制CopyOnWrite的使用场景主要集中在需要高并发读操作而写操作相对较少的场景。这种策略特别适用于那些读操作远多于写操作且写操作不会频繁发生的情况。下面是一些具体的使用场景 并发容器当需要实现线程安全的容器并且读操作远多于写操作时可以使用基于写入时复制的并发容器。这种容器可以确保在读取数据时不需要加锁从而提供高效的并发读取性能。只有在写入数据时才会复制底层数据并进行修改从而保持线程安全。 共享不可变数据在某些情况下多个线程或进程需要共享一些不可变的数据。当这些数据需要更新时可以使用写入时复制策略来创建一个新的数据副本并在副本上进行修改。这样其他线程或进程仍然可以安全地访问原始数据而不会受到修改的影响。 事件处理系统在事件驱动的系统中事件处理函数通常需要读取事件数据并进行处理。如果多个事件处理函数可以同时处理不同的事件并且事件数据在事件处理过程中不会被修改那么可以使用写入时复制的容器来存储事件数据。这样每个事件处理函数都可以安全地读取事件数据而不需要担心数据竞争或一致性问题。 日志记录在日志记录系统中通常需要记录大量的日志信息并且这些日志信息主要是被读取和分析的而不是被修改的。使用写入时复制的容器来存储日志信息可以提高并发写入的性能因为多个线程可以同时写入不同的日志条目而不需要进行复杂的同步操作。 需要注意的是写入时复制策略在写操作频繁或数据量非常大的情况下可能会导致较高的内存开销和性能下降。因此在选择使用写入时复制时需要仔细评估应用场景的读写比例、数据量和性能要求以确保其适用性。此外还需要注意在实现写入时复制策略时正确管理内存和引用计数以避免内存泄漏和其他问题。 6.总结 使用CopyOnWrite思想有以下几个好处 内存效率CopyOnWrite允许多个对象共享相同的数据避免了不必要的数据复制。这对于大型数据结构或多个对象需要引用相同数据的情况下可以节省大量的内存。 性能优化对于很少修改数据的情况下CopyOnWrite可以显著提高性能。由于读操作不需要加锁多个线程可以同时访问共享数据提高并发访问的效率。对于一些读多写少的数据写入时复制的做法就很不错例如配置、黑名单、物流地址等变化非常少的数据这是一种无锁的实现。可以帮我们实现程序更高的并发。 减少数据拷贝CopyOnWrite只在写操作时进行数据拷贝而在读操作时共享数据。这减少了不必要的数据拷贝开销提高了性能。 尽管CopyOnWrite有一些优点但也存在一些缺点或不足之处 写操作开销当有写操作发生时CopyOnWrite需要进行数据的复制这会引入一定的开销。复制大型数据结构可能会消耗较多的时间和内存并且频繁的写操作可能会影响性能 不适合频繁修改的场景由于CopyOnWrite需要进行数据复制所以频繁的写操作会导致性能下降。对于需要频繁修改数据的场景可能有更适合的数据结构或算法选择 总的来说CopyOnWrite适用于多个读操作、少量写操作的场景可以提供高效的内存使用和线程安全的并发访问。但需要权衡其开销和适用性根据具体情况选择使用。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/diannao/92633.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

山东做外贸网站的公司wordpress 注册侧边栏

rgbif版本:3.7.8.1 什么是多值传参? 您是否在使用rgbif时设想过,给某个参数一次性传递许多个值,它将根据这些值独立地进行请求,各自返回独立的结果。 rgbif支持这种工作模式,但是具体的细节需要进一步地…

深圳网站建设公司团队建站园

先说下结论:如果系统不考虑全球化的话,那么我们不用考虑时区的问题,因为我们可以认为中国境内的计算机全部用的是北京时间。1. 时区的来源和划分地球自转一圈是360度,共24小时,所以1小时15度,即&#xff1a…

在什么网站上可以做免费广告wordpress的背景图片

由于需要测试一款40G网卡,下载了 iperf3.1.3 用于性能测试。 iperf3.1.3 源码下载 可以在 iperf 官网 下载源代码: 交叉编译 需要运行在 aarch64 linux 环境下,所以需要交叉编译。 进入iperf3 目录下,运行 ./configure 脚本…

企业网站和信息化建设重庆建站模板展示

1.介绍 1.1 Pandas是什么? Pandas是一个基于NumPy的分析结构化数据的工具集,NumPy为其提供了高性能的数据处理能力。Pandas被普遍用于数据挖掘和数据分析,同时也提供数据清洗、数据I/O、数据可视化等辅助功能。 Github_Star 40k : https://github.com/…

网站开发人员需要去做原型吗有多少人自己做电影网站

在 QML 中,几乎所有组件都继承自 Item 类型,因此它们共享一些通用的属性。 QML 组件通用属性 位置和尺寸 x 和 y: 组件在其父元素中的位置坐标 Item {x: 100y: 100 }width 和 height: 组件的宽度和高度 Item {width: 200height: 100 }z: 组件在 Z 轴…

vps除了做网站还能做什么公共资源交易中心主任级别

Aethir,去中心化GPU云基础设施领导者,宣布其备受期待的节点销售。Aethir是一家企业级的以AI和游戏为重点的GPU即服务提供商。Aethir的去中心化云计算基础设施使GPU提供商能够与需要NVIDIA的H100芯片提供强大AI/ML任务支持的企业客户相连接。 此外&#x…

茂名企业做网站视频剪辑培训比较有名的学校

来源:科学的乐园在科幻小说《三体Ⅲ:死神永生》之中,歌者文明“母世界”的宇宙飞船曾经利用宇宙规律武器二向箔来摧毁地球文明,将地球所处的三维世界完全变成了一个二维世界。很多人无法想象,仅仅一个手机大小的物质&a…

wordpress 分类判断长沙seo排名收费

教育 -C语言程序设计-章节资料考试资料-南京师范大学中北学院【】 第一章 单元测试 1、【单选题】对于计算机来说,最后执行的C语言程序是( ) A、源程序 B、目标程序 C、汇编程序 D、可执行程序 参考资料【 】 2、【单选题】以下叙述中正确的是…

做企业网站一般用什么服务器如何做网站 知乎

版本回退 修改代码 添加第一个版本 接下同上,添加多个版本 回退到上一个版本 回到旧版本(建议实际中操作) 版本回退和回到旧版本的区别: 版本回退:就是删除当前版本,回到以前的版本。 回到旧版…

为网站做外链的方式品牌网站建设必在大蝌蚪

上一篇文章呢,我们讲述了JavaScript运算符中的关系运算符和逻辑运算符,那么紧接上一篇的文章我们今天来说说逻辑运算符。引言逻辑运算符不是很难,也不是很多,我们只要记住三个就可以啦!分别是:!…

找潍坊做网站的赣州网站制作公司

目录 一、磁盘介绍 1. 磁盘数据结构 2. 磁盘的接口类型 3. 磁盘在Linux上的表现形式 二、磁盘分区与MBR 1. 分区优缺点 2. 分区方式 3. MBR分区 4. GPT分区 三、文件系统 1. 文件系统的组成 2. 默认的文件系统 3. 文件系统的作用 4. 模拟破坏文件与修复文件 4…

国内免费网站空间网站建设痛点

一、解释MVC和MVVM架构模式 MVC和MVVM都是常见的前端架构模式,用于抽象分离并解决特定问题。这两种模式在结构上具有一定的相似性,但在细节和数据处理方式上存在一些差异。 MVC,即Model-View-Controller,是一种用于应用程序分层…

电子商务网站开发需求文档北京网站搭建服务

1、在主菜单中选择“模型”→“users and roles”→“users”,新增一个user,其中"name"字段就是要添加的模式名。 2、在新增表时,在表属性的“general”页签中选择"owner",选择刚才新增的user,即可…

网站系统名称怎么填如何给自己的网站做seo

文章目录 变量变量的声明变量命名规则变量的类型 常量常量的定义与初始化字面量常量整型常量浮点型常量字符常量常量表达式(constexpr) 大家好,我是 shopeeai,也可以叫我虾皮,中科大菜鸟研究生。今天我们来一起来学习C…

阿里云 iis 多个网站免费的黄冈网站有哪些

摘要 本文聚集于实战,只讲解最实用的知识点,至于支付起源、在线支付发展历程等科普知识,感兴趣的读者可参考其它优秀的支付类书籍或网络上其它优秀的文章。本章内容对大部分专业概念进行了极致简化,以便更好地帮助读者入门。实际…

网站制作教程:初学者建设银行信用卡网站登录

1. 动态的改变记录级别和策略,即修改log4j.properties,不需要重启Web应用,这需要在web.xml中设置一下。2. 把log文件定在 /WEB-INF/logs/ 而不需要写绝对路径。3. 可以把log4j.properties和其他properties一起放在/WEB-INF/ ,而不是Class-Pat…

宁波企业如何建网站网站开发工程师和软件工程

简介 sar(System Activity Reporter 系统活动情况报告)是目前 Linux 上最为全面的系统性能分析工具之一,可以从多方面对系统的活动进行报告,包括:文件的读写情况、系统调用的使用情况、磁盘 I/O、CPU 效率、内存使用状…

厦门的商城网站建设网站推广项目

一,思路: 简单的字符串处理,当反转字符串后如果字典序减小了,那么肯定不会再执行反转操作,而是执行操作2,将反转后的字符串拼接(这样必定构造一个回文串),那么之后的操作…

网站和软件建站前端网站页面模板

1.水仙花数 打印出所有"水仙花数",所谓"水仙花数"是指一个三位数,其各位数字立方和等于该数本身. 例:1531的三次方5的三次方3的三次方. 法1: #include<stdio.h> int main() {int i 0;int j 0;int k 0;for (i 1; i < 10; i)//百位{for (j …

门户网站建设教程php在网站开发中的作用

4738 Caocaos Bridges 求无向图的桥中最小的那个&#xff0c;tarjan 4739 Zhuge Liangs Mines 状态压缩暴力 4740 The Donkey of Gui Zhou 求两个点在图上的相遇点&#xff0c;模拟dfs 4741 Save Labman No.004 计算几何&#xff0c;平面上的两条…