发一个自己基于 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. 关于onclick中的event对象和element对象

    event.srcElement:引发事件的目标对象,常用于onclick事件. event.fromElement:引发事件的对象源,常用于onmouseout和onmouseover事件. eve ...

  2. SPI 四种模式

    SPI时钟极性CPOL, = 0表示在没有数据传输时为低电平,= 1表示没有数据传输时为高电平. SPI时钟相位CPHA,= 0表示时钟的第一个沿更新数据.第二个沿锁存数据,= 1表示时钟的第一个沿锁 ...

  3. 基于Keil C的覆盖分析,总结出编程中可能出现的几种不可预知的BUG

    基于Keil C的覆盖分析,总结出编程中可能出现的几种不可预知的BUG,供各位网友参考 1.编译时出现递归警告,我看到很多网友都采用再入属性解决,对于再入函数,Keil C不对它进行覆盖分析,采用模拟 ...

  4. VS Visual Studio connection(); Microsoft Visulal Studio vNext & Azure

    http://www.visualstudio.com/connect-event-vs

  5. Remove Nth Node From End of List 解答

    Question Given a linked list, remove the nth node from the end of list and return its head. For exam ...

  6. 探索PHP+Nginx(二) 安装PHP

    首先,我们简单了解一下什么是PHP,PHP(Hypertext Preprocessor 超文本预处理器) 和Java语言一样,PHP也是属于高级语言,并不能直接在操作系统上运行.Java运行需要虚拟 ...

  7. IOS Application生命周期

    第一阶段 - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *) ...

  8. kaggle之电影评论文本情感分类

    电影文本情感分类 Github地址 Kaggle地址 这个任务主要是对电影评论文本进行情感分类,主要分为正面评论和负面评论,所以是一个二分类问题,二分类模型我们可以选取一些常见的模型比如贝叶斯.逻辑回 ...

  9. 四、Mp3文件类型及其判断

    根据前两篇文章的分析,帧分为标签帧和数据帧,MP3文件类型是根据数据帧的类型来分的,文件类型如下表: 位率相等(Constant BitRate) CBR  Mp3文件 位率不等(Variable B ...

  10. android 5.0新特性CardView教程

    CardView 是android5.0新加入的特性,大家先别着急,由于谷歌出了cardview的兼容包,也就是android.support.v7.widget.CardView包,所以在5.0以下 ...