读取-复制-更新(read-copy-update,RCU)是一种高级的互斥机制,在正确的条件下,可以获得高的性能;

RCU对它保护的数据结构做了一些限定,它针对经常发生读而很少发生写的情况做了优化,被保护的资源应该通过指针访问,而对这些资源的引用必须仅由原子代码拥有,在RCU保护的代码范围内不能进入睡眠状态;在修改该数据结构时,写入线程首先复制,然后修改副本,之后用新的版本替换相关指针,当内核确信老的版本上没有其他引用时,就可以释放老的版本了;

使用RCU的代码应该包含<linux/rcupdate.h>头文件;

RCU读操作的使用方法如下,注意反引用的指针不能在RCU锁之外使用;

 rcu_read_lock();

 p = rcu_dereference(ptr);
if (p != NULL) {
/* 读取操作 */
} rcu_read_unlock();

RCU写操作的使用方法如下,首先需要分配一个新的结构,如果必要则从旧的结构中复制数据,然后将读取代码能看到的指针替换掉;

 struct some_struct * new_ptr = kmalloc(...);

 new_prt->xxx = xx;

 rcu_assign_pointer(ptr, new_ptr);

在写端完成之后,剩下的工作就是释放旧的数据结构;当然,这时其他处理器上运行的代码可能扔在引用旧的数据,因此不能立即释放旧的结构;写入代码必须等待直到能够确信不存在这样的引用;

因为拥有对该数据结构的引用的代码都必须是原子的,因此我们可以知道,一旦系统中的每个处理器都至少调用一次后,所有的引用都会消失;因此,RCU所做的就是,设置一个回调函数并等待所有的处理器被调度,之后由回调函数完成清理工作;

RCU提供了两个函数分别为同步等待所有读取结束和异步等待读取结束后释放旧结构资源;

同步:synchronize_rcu(),修改之后调用该函数等待所有读引引用结束,在函数返回之后进行旧资源的释放;

 void synchronize_rcu(void);

异步:call_rcu(),通过该函数注册一个释放旧资源的回调函数,在所有的读访问完成之后,回调注册函数,进行旧资源的释放;

 void call_rcu(struct rcu_head *head, rcu_callback_t func);

Linux设备驱动程序 之 RCU机制的更多相关文章

  1. 【转】linux设备驱动程序中的阻塞机制

    原文网址:http://www.cnblogs.com/geneil/archive/2011/12/04/2275272.html 阻塞与非阻塞是设备访问的两种方式.在写阻塞与非阻塞的驱动程序时,经 ...

  2. 再谈Linux内核中的RCU机制

    转自:http://blog.chinaunix.net/uid-23769728-id-3080134.html RCU的设计思想比较明确,通过新老指针替换的方式来实现免锁方式的共享保护.但是具体到 ...

  3. Linux设备驱动程序学习之分配内存

    内核为设备驱动提供了一个统一的内存管理接口,所以模块无需涉及分段和分页等问题. 我已经在第一个scull模块中使用了 kmalloc 和 kfree 来分配和释放内存空间. kmalloc 函数内幕 ...

  4. Linux设备驱动程序学习----1.设备驱动程序简介

    设备驱动程序简介 更多内容请参考Linux设备驱动程序学习----目录 1. 简介   Linux系统的优点是,系统内部实现细节对所有人都是公开的.Linux内核由大量复杂的代码组成,设备驱动程序可以 ...

  5. linux设备驱动程序-设备树(3)-设备树多级子节点的转换

    linux设备驱动程序--设备树多级子节点的转换 在上一章:设备树处理之--device_node转换成platform_device中,有提到在设备树的device_node到platform_de ...

  6. linux设备驱动程序-i2c(2)-adapter和设备树的解析

    linux设备驱动程序-i2c(2)-adapter和设备树的解析 (注: 基于beagle bone green开发板,linux4.14内核版本) 在本系列linux内核i2c框架的前两篇,分别讲 ...

  7. linux设备驱动程序-i2c(1):i2c总线的添加与实现

    linux设备驱动程序-i2c(1):i2c总线的添加与实现 (基于4.14内核版本) 在上一章节linux设备驱动程序-i2c(0)-i2c设备驱动源码实现中,我们演示了i2c设备驱动程序的源码实现 ...

  8. Linux设备驱动之semaphore机制【转】

    转自:http://blog.csdn.net/xiao229404041/article/details/7031776 Linux设备驱动之semaphore机制在Linux系统中,信号号是一种重 ...

  9. linux设备驱动程序该添加哪些头文件以及驱动常用头文件介绍(转)

    原文链接:http://blog.chinaunix.net/uid-22609852-id-3506475.html 驱动常用头文件介绍 #include <linux/***.h> 是 ...

随机推荐

  1. VBA学习资料分享-1

    近年来,人工智能的概念深入人心,许多企业也正逐步或已推行办公自动化,寻求人力时间成本的降低,从而提升效益.对企业来说,要完全使用人工智能将工作流程自动化恐怕是没那么容易的,可以的话成本也不低,所以使用 ...

  2. Oracle学习笔记:ASCII码转换(chr和ascii函数)

    今天get到一个骚操作,通过ascii码转换之后来进行互换编码的. select chr(ascii('f') + ascii('m') - ascii('a')) from dual; 有必要对as ...

  3. html与css注意事项及小知识点

    html 常用的html特殊符号: 空格:&npsd: 版权所有符号:&copy: 注册商标符号:&reg: 有两个标签容器:<span>和<div> ...

  4. C++ STL 之 map

    #include <iostream> #include <map> using namespace std; // map构造函数 // map<T1, T2> ...

  5. 【Struts2】文件上传与下载

    一.上传 1.1 Struts2实现步骤 浏览器端 服务器端 1.2 关于Struts2中文件上传细节: 1.3 示例 jsp文件 Action类 struts.xml文件配置 二.下载 2.1 文件 ...

  6. Kubernetes对象中的PersistentVolume、PersistentVolumeClaim和StorageClass的概念关系

    Kubernetes容器要持久化数据,离不开volume,k8s的volume和Docker原生概念中的volume有一些差别,不过本次不讲这个,本次要明确的是k8s持久化数据用到的几个对象Persi ...

  7. 并发编程: 生产消费模型、死锁与Rlock、线程、守护线程、信号量、锁

    一.守护进程 二.互斥锁 三.抢票 四.进程间通讯 五.进程间通讯2 一.守护进程 """ 进程间通讯的另一种方式 使用queue queue 队列 队列的特点: 先进的 ...

  8. java——OOM内存泄漏

    资料: 一.什么是OOM OOM,全称“Out Of Memory”,翻译成中文就是“内存用完了”,当JVM因为没有足够的内存来为对象分配空间并且垃圾回收器也已经没有空间可回收时,就会抛出这个erro ...

  9. CAP理论概述

    CAP理论 CAP原则,指在一个分布式系统中,Consistency(一致性).Availability(可用性).Partitiontolerance(分区容错性),三者不可同时拥有. 一致性(C) ...

  10. 解决Spring AOP Controller 不生效

    在spring-mvc.xml文件中,进行以下配置,就可以实现在Controller中, 方法一:最简单的,在spring-mvc.xml配置文件中,添加以下语句 spring-mvc.xml < ...