read write spinlock
发一个自己基于 C++11 写的 read write spinlock,在 MinGW 4.8.2 (gcc 4.8 全面支持c++ 11,但由于gcc windows平台 libstdc++ 目前还不支持 thread,所以用 boost 1.49 及以上版本作为thread库)。
目前在 Xeon E5606 (4核8线程) Win2008 x64平台上测试通过,但还需要在内存弱序的arm上做进一步测试。
代码 spinlock.cpp:
#include<atomic>
#include<cassert> #define SPIN_LOCK_UNLOCK 0
#define SPIN_LOCK_WRITE_LOCK -1 using std::atomic;
using std::atomic_int;
using std::atomic_store_explicit;
using std::atomic_load_explicit;
using std::atomic_compare_exchange_weak_explicit;
using std::memory_order_relaxed;
using std::memory_order_acquire;
using std::memory_order_release; typedef atomic<int> spinlock_t; void rwlock_init(spinlock_t &l)
{
atomic_store_explicit(&l, SPIN_LOCK_UNLOCK, memory_order_relaxed);
} void read_lock(spinlock_t &l)
{
int expected;
int desired; while(true)
{
expected = atomic_load_explicit(&l, memory_order_relaxed); if(expected >= )
{
desired = + expected;
if(atomic_compare_exchange_weak_explicit(&l, &expected, desired, memory_order_relaxed, memory_order_relaxed))
break; // success
}
} atomic_thread_fence(memory_order_acquire); // sync
} void read_unlock(spinlock_t &l)
{
int expected;
int desired; while(true)
{
expected = atomic_load_explicit(&l, memory_order_relaxed); if(expected > )
{
desired = expected - ; atomic_thread_fence(memory_order_release); // sync
if(atomic_compare_exchange_weak_explicit(&l, &expected, desired, memory_order_relaxed, memory_order_relaxed))
break; // success
}
else
{
assert(false);
}
}
} void write_lock(spinlock_t &l)
{
int expected;
int desired; while(true)
{
expected = atomic_load_explicit(&l, memory_order_relaxed); if(expected == SPIN_LOCK_UNLOCK)
{
desired = SPIN_LOCK_WRITE_LOCK;
if(atomic_compare_exchange_weak_explicit(&l, &expected, desired, memory_order_relaxed, memory_order_relaxed))
break; // success
}
} atomic_thread_fence(memory_order_release); // sync
} void write_unlock(spinlock_t &l)
{
int expected;
int desired; while(true)
{
expected = atomic_load_explicit(&l, memory_order_relaxed); if(expected == SPIN_LOCK_WRITE_LOCK)
{
desired = SPIN_LOCK_UNLOCK; atomic_thread_fence(memory_order_release); // sync
if(atomic_compare_exchange_weak_explicit(&l, &expected, desired, memory_order_relaxed, memory_order_relaxed))
break; // success
}
else
{
assert(false);
}
}
} //#include<thread>
#include<boost/thread.hpp>
#include<iostream> spinlock_t g_lock;
long g_total;
const int count = ; void add_job()
{
for(int i = ; i < count; ++i)
{
write_lock(g_lock);
++g_total;
std::cout << "Thread ++ " << boost::this_thread::get_id() << std::endl;
write_unlock(g_lock);
}
} void read_job()
{
for(int i = ; i < count; ++i)
{
read_lock(g_lock);
std::cout << g_total << std::endl;;
read_unlock(g_lock);
}
} int main()
{
g_total = ;
rwlock_init(g_lock); boost::thread th1(add_job);
boost::thread th2(add_job); boost::thread th3(read_job);
boost::thread th4(read_job);
boost::thread th5(read_job); th1.join();
th2.join();
th3.join();
th4.join();
th5.join(); std::cout << "The total: " << g_total << std::endl;
}
编译命令行:
g++ -std=c++ -Wall -O2 spinlock.cpp -I/d/Sources/boost_1_55_0 -L /d/Sources/boost_1_55_0/stage/lib/ -lboost_thread-mgw48-mt-1_55 -lboost_system-mgw48-mt-1_55
其它类型 spin lock
1)最简单(非读写)的 spinlock 可以参考 boost::atomic 里面示例 ;
2)Linux kernel 中还有一类 write prefer 的spin lock,了解原理后也很容易实现,原理可以参考文档 Linux Kernel Development 3rd。
read write spinlock的更多相关文章
- 装逼名词-ABA CAS SpinLock
今天看wiki,看到一个提到什么什么会陷入 race condition & ABA problem.丫的我没听过ABA呀,那么我去搜了一下,如下: http://www.bubuko.com ...
- 【C#】【Thread】SpinLock
SpinLock结构是一个低级别的互斥同步基元,它在等待获取锁时进行旋转. 在多核计算机上,当等待时间预计较短且极少出现争用情况时,SpinLock 的性能将高于其他类型的锁. 不过,我们建议您仅在通 ...
- 锁相关知识 & mutex怎么实现的 & spinlock怎么用的 & 怎样避免死锁 & 内核同步机制 & 读写锁
spinlock在上一篇文章有提到:http://www.cnblogs.com/charlesblc/p/6254437.html 通过锁数据总线来实现. 而看了这篇文章说明:mutex内部也用到 ...
- Linux内核原子(1) - spinlock的实现
spinlock的数据结构spinlock_t定义在头文件linux/spinlock_types.h里面: typedef struct { raw_spinlock_t raw_lock; #if ...
- [20140829]spinlock导致cpu居高不下
背景: 出现cpu高于常规的告警 排查: 1.开跟踪,没有发现cup特别高的查询 2.查看内核cpu使用量,看是否是sql server 端引起 3.查看负荷,是否负荷特别高这里使用 batch re ...
- spinlock原理
[参考] http://www.searchtb.com/2011/06/spinlock%E5%89%96%E6%9E%90%E4%B8%8E%E6%94%B9%E8%BF%9B.html
- 自旋锁-SpinLock(.NET 4.0+)
短时间锁定的情况下,自旋锁(spinlock)更快.(因为自旋锁本质上不会让线程休眠,而是一直循环尝试对资源访问,直到可用.所以自旋锁线程被阻塞时,不进行线程上下文切换,而是空转等待.对于多核CPU而 ...
- 重新想象 Windows 8 Store Apps (48) - 多线程之其他辅助类: SpinWait, SpinLock, Volatile, SynchronizationContext, CoreDispatcher, ThreadLocal, ThreadStaticAttribute
[源码下载] 重新想象 Windows 8 Store Apps (48) - 多线程之其他辅助类: SpinWait, SpinLock, Volatile, SynchronizationCont ...
- 【linux】spinlock 的实现
一.什么是spinlock spinlock又称自旋锁,是实现保护共享资源而提出一种锁机制.自旋锁与互斥锁比较类似,都是为了解决对某项资源的互斥使用 无论是互斥锁,还是自旋锁,在任何时刻,最多只能有一 ...
- atomic, spinlock and mutex性能比较
我非常好奇于不同同步原理的性能,于是对atomic, spinlock和mutex做了如下实验来比较: 1. 无同步的情况 #include <future> #include <i ...
随机推荐
- eMMC的MMC模式与SPI模式
MMC存贮卡可以分为MMC和SPI两种工作模式,MMC模式是标准的默认模式,具有MMC的全部特性.而SPI模式则是MMC存贮卡可选的第二种模式,这个模式是MMC协议的一个子集,主要用于只需要小数量的卡 ...
- Slack 开源替代品 Rocket.Chat(聊天,文件上传等等)
Rocket.Chat 是特性最丰富的 Slack 开源替代品之一. 主要功能:群组聊天,直接通信,私聊群,桌面通知,媒体嵌入,链接预览,文件上传,语音/视频 聊天,截图等等. Rocket.Chat ...
- wireshark----教你如何抓包
wireshark----教你如何抓包 wireshark是一款强大的抓包工具,走过路过一定不要错过就是了,当你学习TCP/IP协议的时候,学习使用wireshark 抓包正是理论联系实际最好的方法, ...
- 微型 Python Web 框架 Bottle - Heroin blog
微型 Python Web 框架 Bottle - Heroin blog 微型 Python Web 框架 Bottle
- Grails重定向以及Render、Session的使用
近期发现网上grails因为用的人不算非常多,相关的资料也不是那么easy找到,随着学习的深入打算把我的学习心得定期分享出来.也给学习grails的同胞一个偷懒的机会,我的原则是以最简洁的方式学会Gr ...
- MVC4 jquery 样式 主题 用法(案例)
MVC4已经自带了jquery,新建的项目,基本上什么都不用添加就可以运行,跑项目.(集成了那么多东西,jquery,modernizr,自带的默认权限,生成的模板,但是缺没有一个统一的文档或者什么去 ...
- 深入浅出NodeJS——异步I/O
底层操作系统,异步通过信号量.消息等方式有着广泛的应用. PHP语言从头到尾都是以同步堵塞方式执行,利于程序猿顺序编写业务逻辑. 异步I/O.事件驱动.单线程构成Node的基调. why异步I/O ( ...
- Jquery如何获取控件ID
l 1.#id 用法: $(”#myDiv”); 返回值 单个元素的组成的集合 说明: 这个就是直接选择html中的id=”myDiv” l 2.Element 用法: ...
- AjaxHelper创建的ajax无效,JQuery直接方法post有效,原来是Microsoft.jQuery.Unobtrusive.Ajax错误,NuGet解决
Get-Package -ListAvailable -Filter Microsoft.JQuery Microsoft.jQuery.Unobtrusive.Ajax –Version 3.2.0
- Cisco密码恢复
1.利用超级终端连接路由器,重新启动路由器,按CTRL+BREAK进入ROM监控模式 注:配置寄存器(2B)第六位控制是否读取NVRAM中的配置文件 2.修改配置寄存器:2600系列:1): con ...