RCU

RUC是什么?

  • RCU(Read-Copy-Update)是一种用于并发编程的技术,旨在提供高效且无锁(lock-free)的读操作,同时保证数据一致性和并发性。

也就是说他并不需要锁的机制来保障数据一致性和并发现.

1.RCU的实现原理

  • RCU的实现本质上是为了解决读写锁的问题,因为读者可以多数的问题,而写锁互斥的性质,会导致其他读锁也被阻塞,因此会造成一定上的性能开销.

而RCU的关键就是在更新下拷贝(Copy),因此他的实现机制大致如下:

  1. 初始阶段: 在初始阶段,所有读取线程可以同时访问共享数据,而不需要任何同步机制。这是因为在此阶段,尚未发生任何写操作,因此读取操作不会访问到不一致或无效的数据。
  2. 更新阶段: 当需要修改共享数据时,RCU采用一种"写时复制"(copy-on-write)的策略。它首先创建一个新的数据副本,然后将修改应用于该副本,而不是直接修改共享数据。这确保了在更新期间,读取线程仍然可以访问到旧版本的数据,而不会被更新操作所影响。
  3. 发布阶段: 在更新完成后,RCU使用一种特定的机制来通知读取线程有新的数据副本可用。这个机制可以是类似于发布-订阅的模型,其中读取线程可以订阅通知,并在新的数据副本发布时接收到通知。通过这个发布机制,读取线程可以感知到新的数据副本,并在需要时切换到新版本的数据。
  4. 回收阶段: 在发布新的数据副本后,旧版本的数据并不立即被回收。RCU采用一种延迟回收的策略,在确认所有读取线程都不再使用旧数据副本之后,才进行回收操作。这通常涉及使用计数器或其他形式的跟踪机制,以确保在旧版本的数据没有被使用时进行回收,从而避免破坏读取线程的正确性。

2.订阅/发布机制

其实订阅/发布机制不光可以用来修改数据,他的本身也是一种通知信息的方式,所以无论是插入,删除还是修改都可以的.

  • 而订阅/发布机制其实为我们实现的就是:让读者在写者更新时,要么读的旧的值,要么读到新的值,而不能观察到中间的任何结果.

而这种机制的实现得以于很重要的一点:单拷贝原子性

什么是单拷贝原子性?

意思就是CPU均提供对地址对齐的单一读写操作的原子性保证,其支持的位宽往往与CPU的位宽一致.

什么是地址对齐?

地址对齐是指在访问计算机内存中的数据时,数据的起始地址与数据的长度之间存在特定的对齐关系。

在大多数计算机系统中,数据的存储是以字节为单位的,而不同类型的数据(如整数、浮点数等)可能需要不同长度的存储空间。对齐要求是为了确保数据在内存中的存储和访问的效率以及硬件的正常工作。

最常见的案例就是:C语言中的结构体:

例如:

struct Person {
char name[10]; // 10 字节
int age; // 4 字节
float height; // 4 字节
};

根据常理来说,是18个字节的内存大小,实际上输出的结果是这样的:

20
Process returned 0 (0x0) execution time : 0.014 s
Press any key to continue.
  • 先给答案,这里的char类型的数组把他看成一个一个1字节的char类型组和而成,而编译器会根据字长对齐的方式,也就是根据4字节来对齐,因此name数组实际上是12个字节,因此12+4+4 = 20个字节;

    实际上地址对齐根据编译器有相对应的规则,但一般来说具备一些规则:

    • 结构体总体大小能够被最宽的成员的大小整除,如不能则在后面补充字节
    • 每个成员相对于起始地址的偏移能够被其自身大小整除

而之前的那句话含义就是对于单个机器字长的读写操作,即读写操作的数据大小和处理器的位长相同的情况下,CPU会提供一定的原子性保护,这是基于硬件的实现.也就意味着要么完全执行,要么不执行,因此机器的执行只有0和1两个结果,因此不会出现中间态就是这个原因

现在再来看订阅/发布机制:

例如,链表中插入一个新的节点:

  • 第一步就是初始化节点了C,然后让C的指向了B

  • 第二步则是通过更新节点A的指针,指向了C,此时因为原子性的保证,即操作的结果被读者读到只可能是读前和读后.

    因此如果是读前的状态,则依然是记录了B,读后则记录了新插入的结点可以遍历到C,而当读者去遍历A结点的时候,查找下一个结点这个操作就是订阅,而发布则是通过更新A的指针操作来实现,因此他们的本质实际上是一种读写操作


3.宽限期

宽限期是什么?

之前我们聊过在回收阶段,RCU会延迟回收,而就是基于这个回收期,因为旧的数据不能排除还有读者在使用的情况,因此为了确定何时能够回收这个资源,RCU引入了一个叫宽限期的概念.

  • 而宽限期的长度,是一个应该去权衡的问题:

    1. 例如读者操作的时间会影响宽限期的长度
    2. 系统的负载和性能需求,宽限期太长对于系统的负载来说也比较高.

因此,合理的去设置宽限期是一个权衡考虑的结果,根据具体的应用需求,性能要求来真正决定.

为此RCU为读者提供了两个接口rcu_read_lock和,rcu_read_unlock去分别标记读临界区的开始和结束,这里并不是意味着用加锁的方式去保护临界区,其具体的实现由于本人能力不足,而RCU的机制在Linux2.5版本及以上才慢慢出现.

同样RCU也会为写者提供接口synchronize_rcu,用于阻塞写者等到宽限期结束.其RCU的内部具体实现还需要去参考Linux源码理解.

RCU的简单认识的更多相关文章

  1. 一个rcu回调导致的简单死锁

    在自有模块的处理中,我们设计了一个内核线程去做gc, 但同时,我们又用到了rcu,rcu中也会去抢gc的锁,由于该锁用的spin_lock,而不是spin_lock_bh,并没有关软中断,所以在rcu ...

  2. Linux2.6.11版本:classic RCU的实现

    转载自:http://www.wowotech.net/kernel_synchronization/linux2-6-11-RCU.html 一.前言 无论你愿意或者不愿意,linux kernel ...

  3. Linux 2.6内核中新的锁机制--RCU

    转自:http://www.ibm.com/developerworks/cn/linux/l-rcu/ 一. 引言 众所周知,为了保护共享数据,需要一些同步机制,如自旋锁(spinlock),读写锁 ...

  4. 基数树与RCU锁

    基数树是一种用空间换时间的数据结构,通过空间的冗余减少时间上的消耗.radix tree很适合稀疏的结构! 自从把RCU机制引入到基树中来,这里就有了个协议叫做:lockless的page-cache ...

  5. linux 内核 RCU机制详解

    RCU(Read-Copy Update)是数据同步的一种方式,在当前的Linux内核中发挥着重要的作用.RCU主要针对的数据对象是链表,目的是提高遍历读取数据的效率,为了达到目的使用RCU机制读取数 ...

  6. SOA_环境安装系列2_Oracle RCU安装和环境搭建(案例)

    2015-01-02 Created By BaoXinjian

  7. RCU 机制 [转IBM]

    2005 年 7 月 01 日 本文详细地介绍了 Linux 2.6 内核中新的锁机制 RCU(Read-Copy Update) 的实现机制,使用要求与典型应用. 一.引言 众所周知,为了保护共享数 ...

  8. Redis 安装与简单使用

    安装 Redis 一般系统都会有软件管理工具,但是通常版本都不会太新,况且 Redis 的安装很简单,因此下面使用源码的安装方式. 下载源码 wget http://download.redis.io ...

  9. 内核中的锁机制--RCU

    一. 引言 众所周知,为了保护共享数据,需要一些同步机制,如自旋锁(spinlock),读写锁(rwlock),它们使用起来非常简单,而且是一种很有效的同步机制,在UNIX系统和Linux系统中得到了 ...

  10. Linux RCU 机制详解

    1.简介: RCU(Read-Copy Update)是数据同步的一种方式,在当前的Linux内核中发挥着重要的作用. RCU主要针对的数据对象是链表,目的是提高遍历读取数据的效率,为了达到目的使用R ...

随机推荐

  1. 【Python】sqlmodel: Python 数据库管理ORM 的终极形态?

    ORM 大家都知道ORM(Object Relational Mapping)是一种将对象和关系数据库中的表进行映射的技术,它可以让开发者更加方便地操作数据库,而不用直接使用SQL语句. 直接使用SQ ...

  2. 手记系列之六 ----- 分享个人使用kafka经验

    前言 本篇文章主要介绍的关于本人从刚工作到现在使用kafka的经验,内容非常多,包含了kafka的常用命令,在生产环境中遇到的一些场景处理,kafka的一些web工具推荐等等.由于kafka这块的记录 ...

  3. RDD练习:词频统计

    一.词频统计: 1.读文本文件生成RDD lines lines=sc.textFile("file:///home/hadoop/word.txt") #读取本地文件 lines ...

  4. 获取邮箱(QQ、126、163)的客户端授权码

    获取QQ邮箱的客户端授权码 1.首先登录QQ邮箱(https://mail.qq.com),然后,点击"设置"按钮. 2.点击"账户"按钮,进入"账户 ...

  5. Flex布局常用属性详解

    1. Flex布局与响应式布局 1.1 为什么需要响应式布局? 在电脑PC端,使用浮动,定位同时使用像素px单位就可以完成大部分布局,而且布局完之后不会有大问题,但是到了移动端,移动设备的屏幕尺寸多种 ...

  6. .Net Core 如何数据导出 Excel?(EPPlus->OfficeOpenXml 实现固定列和动态列导出)

    〇.前言 对于将数据以 Excel 表格文件输出,还是比较常用的,也存在诸多情况,比如列固定或不固定.数据类型为 List<T>或 Json 对象等. 本文通过包 OfficeOpenXm ...

  7. 消灭非稳态噪音的利器 - AI 降噪

    摘要:轻量级神经网络降噪方法,解析 ZegoAIDenoise 的算法实现! 文|即构引擎开发团队 一.轻量级神经网络降噪--ZegoAIDenoise 当下,用户在进行音频通话时常常置身于各种不同的 ...

  8. pandas: 设置列名&获取所有列名

    解决方案 download_page_data_df.columns = column_name2excel 参考链接 https://www.cnblogs.com/bigtreei/p/10145 ...

  9. VScode 中golang 调试 F5,json文件内容更改 Go

    调试:在Vscode软件中调试.go文件代码 1.1.1 确保调试文件正常运行 准备好.go文件,并且该文件能正常运行,终端输入命令运行程序,如:go run time.go 测试代码: packag ...

  10. docker service 与 docker stack

    转载请注明出处: 1. Docker Service Docker Service(服务)是用于定义和管理单个容器服务的概念.它是在Docker Swarm集群中运行的容器实例,可以使用docker ...