无锁编程(五) - RCU(Read-Copy-Update)
RCU(Read-Copy Update)
RCU就是指读-拷贝修改,它是基于其原理命名的。对于被RCU保护的共享数据结构,读操作不需要获得任何锁就可以访问,但写操作在访问它时首先拷贝一个副本,然后对副本进行修改,最后在适当的时机把指向原来数据的指针重新指向新的被修改的数据。这个时机就是所有引用该数据的CPU都退出对共享数据的操作。
Linux内核中内存管理大量的运用到了RCU机制。为每个内存对象增加了一个原子计数器用来继续该对象当前访问数。当没有其他进程在访问该对象时(计数器为0),才允许回收该内存。
从这个流程可以看出,RCU类似于一种读写锁的优化,用于解决读和写之间的同步问题。比较适合读多,写少的情况,当写操作过多的时候,这里的拷贝和修改的成本同样也很大。(写操作和写操作之间的同步还需要其它机制来保证)。
代码讲解:
#include <stdio.h>
#include <pthread.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h> pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
int currentidx = 0;
char* str[2] = {0}; void* consume(void *arg)
{
sleep(1);
while(1)
{
printf("************************consumed %s, index %d, self %d\n",str[currentidx], currentidx, pthread_self());
sleep(1);
} return NULL;
} void* produce( void * arg )
{
const char* s_str1 = "hello";
const char* s_str2 = "world"; while(1)
{
printf("product begin\n"); // read copy
int other = 1 - currentidx;
str[other] = (char*)malloc(6);
if (other == 0)
{
strncpy(str[other], s_str1, 6);
}
else
{
strncpy(str[other], s_str2, 6);
} // update原子的修改索引
currentidx = other;
// delete old currentidx
free(str[1-currentidx]);
sleep(5);
} return NULL;
} int main( void )
{
pthread_t thread1,thread2;
pthread_create(&thread1, NULL, &produce, NULL );
pthread_create(&thread2, NULL, &consume, NULL );
pthread_join(thread1,NULL);
pthread_join(thread2,NULL);
return 0;
}
结果说明:
[root@rocket lock-free]# ./lockfree_rcu
product begin
************************consumed world, index1, self 1395513088
************************consumed world, index1, self 1395513088
************************consumed world, index1, self 1395513088
************************consumed world, index1, self 1395513088
product begin
************************consumed hello, index0, self 1395513088
************************consumed hello, index0, self 1395513088
************************consumed hello, index0, self 1395513088
************************consumed hello, index0, self 1395513088
************************consumed hello, index0, self 1395513088
product begin
************************consumed world, index1, self 1395513088
************************consumed world, index1, self 1395513088
************************consumed world, index1, self 1395513088
************************consumed world, index1, self 1395513088
************************consumed world, index1, self 1395513088
版权声明:本文为博主原创文章,未经博主允许不得转载。
无锁编程(五) - RCU(Read-Copy-Update)的更多相关文章
- [转]透过 Linux 内核看无锁编程
非阻塞型同步 (Non-blocking Synchronization) 简介 如何正确有效的保护共享数据是编写并行程序必须面临的一个难题,通常的手段就是同步.同步可分为阻塞型同步(Blocking ...
- 无锁编程以及CAS
无锁编程 / lock-free / 非阻塞同步 无锁编程,即不使用锁的情况下实现多线程之间的变量同步,也就是在没有线程被阻塞的情况下实现变量的同步,所以也叫非阻塞同步(Non-blocking Sy ...
- 无锁编程(一) - Double-checked Locking
Double-checked Locking,严格意义上来讲不属于无锁范畴,无论什么时候当临界区中的代码仅仅需要加锁一次,同时当其获取锁的时候必须是线程安全的,此时就可以利用 Double-che ...
- 4.锁--无锁编程以及CAS
无锁编程以及CAS 无锁编程 / lock-free / 非堵塞同步 无锁编程,即不使用锁的情况下实现多线程之间的变量同步,也就是在没有线程被堵塞的情况下实现变量的同步,所以也叫非堵塞同步(Non-b ...
- 海量并发的无锁编程 (lock free programming)
最近在做在线架构的实现,在线架构和离线架构近线架构最大的区别是服务质量(SLA,Service Level Agreement,SLA 99.99代表10K的请求最多一次失败或者超时)和延时.而离线架 ...
- 无锁编程 - Double-checked Locking
Double-checked Locking,严格意义上来讲不属于无锁范畴,无论什么时候当临界区中的代码仅仅需要加锁一次,同时当其获取锁的时候必须是线程安全的,此时就可以利用 Double-check ...
- 【Java并发编程】2、无锁编程:lock-free原理;CAS;ABA问题
转自:http://blog.csdn.net/kangroger/article/details/47867269 定义 无锁编程是指在不使用锁的情况下,在多线程环境下实现多变量的同步.即在没有线程 ...
- C++11原子操作与无锁编程(转)
不讲语言特性,只从工程角度出发,个人觉得C++标准委员会在C++11中对多线程库的引入是有史以来做得最人道的一件事:今天我将就C++11多线程中的atomic原子操作展开讨论:比较互斥锁,自旋锁(sp ...
- C++性能榨汁机之无锁编程
C++性能榨汁机之无锁编程 来源 http://irootlee.com/juicer_lock_free/ 前言 私以为个人的技术水平应该是一个螺旋式上升的过程:先从书本去了解一个大概,然后在实践中 ...
随机推荐
- PowerDesigner(一)-PowerDesigner概述(系统分析与建模)(转)
PowerDesigner概述 PowerDesigner是Sybase公司推出的一个集成了企业架构,UML(统一建模语言)和数据库的CASE(计算机辅助软件工程)工具.它不仅可以用于系统设计和开发的 ...
- HDOJ1050
Moving Tables Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)Tot ...
- Excel每隔两行自动求和一次怎么操作?
今天ytkah得到一份数据,要求进行统计分析,由于是原始数据,还没处理过,数据量有点大,如下图所示(Excel每隔两行自动求和),每天的数字由两项组成,男生的人数.消费值和女生的人数和消费值,数字都在 ...
- css两个form不换行,两个div并排代码
1.form不换行通过table布局实现 <table> <tr> <td> <form method="get" action=&quo ...
- allow_url_include和allow_url_fopen
allow_url_fopen没什么好说的,主要是allow_url_include 从PHP5.2开始allow_url_include就默认为Off了,而allow_url_fopen一直是On的 ...
- ASP.NET MVC的处理管线
原文:http://www.cnblogs.com/fzrain/p/3651693.html 下面开始解释各个部分: 路由模块 1.在ASP.NET MVC处理管线中的第一站就是路由模块.当请求到达 ...
- 运行时修改TimerTask的执行周期
java.util.TimerTask类的执行周期period变量的声明如下: /** * Period in milliseconds for repeating tasks. A positive ...
- UVALive6571 It Can Be Arranged(最小路径覆盖)
题意:现在有n个课程,每个课程有一定的参与人数,然后每个课程有开始时间和结束时间ai,bi. 而且给定了一个矩阵clean(ij),表示的是上完i课程需要clean[i][j]的时间打扫卫生才能继续上 ...
- cf div2 238 D
D. Toy Sum time limit per test 1 second memory limit per test 256 megabytes input standard input out ...
- 详解 $_SERVER 函数中QUERY_STRING和REQUEST_URI区别
详解 $_SERVER 函数中QUERY_STRING和REQUEST_URI区别 http://blog.sina.com.cn/s/blog_686999de0100jgda.html 实例: ...