无锁编程(五) - 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/ 前言 私以为个人的技术水平应该是一个螺旋式上升的过程:先从书本去了解一个大概,然后在实践中 ...
随机推荐
- 项目分析(PLUG)
plug过程 .INIT_PLUG #define INIT_PLUG Plug::InitPlug g_InitPlug(true); //共享内存数据结构 struct PlugShareMemo ...
- Metasploit命令大全
Metasploit是一款开源的安全漏洞检测工具,可以帮助安全和IT专业人士识别安全性问题,验证漏洞的缓解措施,并管理专家驱动的安全性进行评估,提供真正的安全风险情报.这些功能包括智能开发,密码审计, ...
- 一个奇怪的网络故障 默认网关为0.0.0.0(Windows)
用IPCONFIG命令看到的情况是这样: Windows IP 配置 以太网适配器 本地连接 : 连接特定的 DNS 后缀 . . . . . . . : 本地链接 IPv6 地址. . . . . ...
- Sqli-labs less 32
Less-32 利用上述的原理,我们可以进行尝试payload为: http://127.0.0.1/sqli-labs/Less-32/?id=-1%df%27union%20select%201, ...
- Sqli-labs less 42
Less-42 Update更新数据后,经过mysql_real_escape_string()处理后的数据,存入到数据库当中后不会发生变化.在select调用的时候才能发挥作用.所以不用考虑在更新密 ...
- BZOJ1083: [SCOI2005]繁忙的都市
水题之王SP…这题就裸的最小生成树 /************************************************************** Problem: 1083 User ...
- NodeJS模块、包、NPM
1.NodeJS模块 每一个Nodejs都是一个NodeJS模块,包括JS文件,JSON文本文件,二进制模块文件. a.模块的应用 新建一个文件mytest. ...
- ASP.NET 4.5新特性WebAPI从入门到精通
在新出的MVC4中,增加了WebAPI,用于提供REST风格的WebService,新生成的WebAPI项目和典型的MVC项目一样,包含主要的Models.Views.Controllers等文件夹和 ...
- iOS-xib(使用XIB实现嵌套自定义视图)
参考:http://wtlucky.github.io/geekerprobe/blog/2014/08/10/nested-xib-views/?utm_source=tuicool 因为主要练习x ...
- POJ 2041
#include <iostream> #include <string> #include <algorithm> using namespace std; st ...