发一个自己基于 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的更多相关文章

  1. 装逼名词-ABA CAS SpinLock

    今天看wiki,看到一个提到什么什么会陷入 race condition & ABA problem.丫的我没听过ABA呀,那么我去搜了一下,如下: http://www.bubuko.com ...

  2. 【C#】【Thread】SpinLock

    SpinLock结构是一个低级别的互斥同步基元,它在等待获取锁时进行旋转. 在多核计算机上,当等待时间预计较短且极少出现争用情况时,SpinLock 的性能将高于其他类型的锁. 不过,我们建议您仅在通 ...

  3. 锁相关知识 & mutex怎么实现的 & spinlock怎么用的 & 怎样避免死锁 & 内核同步机制 & 读写锁

    spinlock在上一篇文章有提到:http://www.cnblogs.com/charlesblc/p/6254437.html  通过锁数据总线来实现. 而看了这篇文章说明:mutex内部也用到 ...

  4. Linux内核原子(1) - spinlock的实现

    spinlock的数据结构spinlock_t定义在头文件linux/spinlock_types.h里面: typedef struct { raw_spinlock_t raw_lock; #if ...

  5. [20140829]spinlock导致cpu居高不下

    背景: 出现cpu高于常规的告警 排查: 1.开跟踪,没有发现cup特别高的查询 2.查看内核cpu使用量,看是否是sql server 端引起 3.查看负荷,是否负荷特别高这里使用 batch re ...

  6. spinlock原理

    [参考] http://www.searchtb.com/2011/06/spinlock%E5%89%96%E6%9E%90%E4%B8%8E%E6%94%B9%E8%BF%9B.html

  7. 自旋锁-SpinLock(.NET 4.0+)

    短时间锁定的情况下,自旋锁(spinlock)更快.(因为自旋锁本质上不会让线程休眠,而是一直循环尝试对资源访问,直到可用.所以自旋锁线程被阻塞时,不进行线程上下文切换,而是空转等待.对于多核CPU而 ...

  8. 重新想象 Windows 8 Store Apps (48) - 多线程之其他辅助类: SpinWait, SpinLock, Volatile, SynchronizationContext, CoreDispatcher, ThreadLocal, ThreadStaticAttribute

    [源码下载] 重新想象 Windows 8 Store Apps (48) - 多线程之其他辅助类: SpinWait, SpinLock, Volatile, SynchronizationCont ...

  9. 【linux】spinlock 的实现

    一.什么是spinlock spinlock又称自旋锁,是实现保护共享资源而提出一种锁机制.自旋锁与互斥锁比较类似,都是为了解决对某项资源的互斥使用 无论是互斥锁,还是自旋锁,在任何时刻,最多只能有一 ...

  10. atomic, spinlock and mutex性能比较

    我非常好奇于不同同步原理的性能,于是对atomic, spinlock和mutex做了如下实验来比较: 1. 无同步的情况 #include <future> #include <i ...

随机推荐

  1. USB系列之五:用汇编实现的一些USB功能

    前面的USB系列一至四,实现了我们需要的一些USB功能,但都是用C语言的32位代码,之后我们插进了三篇关于DOS下设备驱动程序的文章,我们现在应该清楚,当我们要在DOS下写一个U盘的驱动时,最好使用汇 ...

  2. Arcgis api For silverlight 加载高德地图

    原文 http://www.cnblogs.com/thinkaspx/archive/2012/11/13/2767752.html 地图仅供演示,研究使用.如要商用 请联系厂商. public c ...

  3. You don't seem to have 'make' or 'gmake' in your PATH

    标题尚的错误,不是原因,因为which make的时候是有显示/usr/bin/make的,echo $PATH的时候也是有make的路径的. 编译Qt  ./configure的时候出现标题上错误, ...

  4. MIT-scheme安装

    下载地址: http://www.gnu.org/software/mit-scheme/ 下载windows版本,安装. The MIT-Scheme can be installed by jus ...

  5. 在Activity中响应ListView内部按钮的点击事件的两种方法!!!

    在Activity中响应ListView内部按钮的点击事件的两种方法 转载:http://www.cnblogs.com/ivan-xu/p/4124967.html 最近交流群里面有人问到一个问题: ...

  6. Libgdx开发ios游戏

    今天亲自尝试了LibGDX如何开发ios游戏, 必须条件: 1:mac操作系统,mac下必须安装Xcode     好像ios开发必须在mac操作系统下 2:mac下安装eclipse 3:eclip ...

  7. IEEE发布2016年度编程语言排行榜

    C 语言占据榜首,但大数据类是最大赢家. IEEE Spectrum 的第三次"最受欢迎编程语言"交互式排行榜新鲜出炉.因为不可能顾及到每一个程序员的想法,Spectrum 使用多 ...

  8. ARM LDR伪指令使用方法具体解释

    LDR伪指令 10.45 LDR pseudo-instruction   功能:把一个32位马上数或一个32位的内存地址载入到一个寄存器中. 注意:这里描写叙述的是LDR伪指令,而不是LDR指令   ...

  9. ACM学习-POJ-1125-Stockbroker Grapevine

    菜鸟学习ACM,纪录自己成长过程中的点滴. 学习的路上,与君共勉. ACM学习-POJ-1125-Stockbroker Grapevine Stockbroker Grapevine Time Li ...

  10. strcpy与memcpy的区别

    strcpy和memcpy的区别 strcpy和memcpy都是标准C库函数,它们有下面的特点. strcpy提供了字符串的复制.即strcpy只用于字符串复制,并且它不仅复制字符串内容之外,还会复制 ...