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. Hugging News #0616: 有几项非常重要的合作快来围观、最新中文演讲视频回放发布!

    每一周,我们的同事都会向社区的成员们发布一些关于 Hugging Face 相关的更新,包括我们的产品和平台更新.社区活动.学习资源和内容更新.开源库和模型更新等,我们将其称之为「Hugging Ne ...

  2. 基于html2canva jspdf 实现前端页面加水印 并导出页面PDF

    基于html2canva jspdf 实现前端页面加水印 并导出页面PDF; 下载完整代码请访问uni-app插件市场地址:https://ext.dcloud.net.cn/plugin?id=12 ...

  3. Terraform 系列-使用 for-each 对本地 json 进行迭代

    系列文章 Terraform 系列文章 Grafana 系列文章 概述 前文 Grafana 系列 - Grafana Terraform Provider 基础 介绍了使用 Grafana Terr ...

  4. List 接口及其常用方法

    List 接口基本介绍 List接口是Collection接口的子接口,其主要特点如下: List中元素有序,是按照元素的插入顺序进行排序的.每个元素都有一个与之关联的整数型索引(索引从 0 开始), ...

  5. Kafka 如何保证消息不被重复消费?或者说,如何保证消息消费的幂等性?

    如何保证消息不被重复消费?或者说,如何保证消息消费的幂等性? >幂等性,通俗点说,就一个数据,或者一个请求,给你重复来多次,你得确保对应的数据是不会改变的,不能出错. kafka 的机制:  K ...

  6. gRPC vs. HTTP:网络通信协议的对比

    概述 gRPC 和 HTTP 是两种常见的网络通信协议,用于在客户端和服务器之间进行通信.它们具有不同的特点和适用场景,下面对它们进行详细比较. HTTP(Hypertext Transfer Pro ...

  7. Python 引用问题 - ImportError: attempted relative import with no known parent package

    问题描述 近日在尝试引用其他文件的代码时,遇到了错误: ImportError: attempted relative import with no known parent package. 问题大 ...

  8. 个人博客迁移到托管平台Netlify

    Netlify是一家国外的静态网站的托管平台,提供免费的https,自动化部署和升级,可以监控GitHub.GitLab或者Bitbucket做到自动更新发布. 个人体会访问速度不是很理想,不如部署在 ...

  9. 内核源码中单个.o文件的编译过程(六)

    通过对过渡篇的学习,相信你已经具有了相当的知识储备,接下来就来继续学习单个.o文件的编译过程 以/drivers/char/mem.c的编译为例 make /drivers/char/mem.o 一. ...

  10. 2023年郑州轻工业大学校赛邀请赛mjh

    首先,很感谢老师的信任,选择我去参加此次比赛:其次,感谢wh,wyh两位队友的全程带飞.此次比赛是我第一次参加线下的比赛活动,内心难免激动与紧张. 比赛开始,队友直接找到了签到题进行解答,而我拿到了看 ...