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 ...
随机推荐
- Qt5中生成和使用静态库
在QT中静态库的后缀名为.a,在vs中开发的静态库后缀名为.lib.QT版本为5.2.1,系统为Windows. 一. 静态库的生成 新建项目. 新建一个静态库的项目,如图1.1所示:项目名称为tes ...
- Delphi中的异常处理(10种异常来源、处理、精确处理)
一.异常的来源 在Delphi应用程序中,下列的情况都比较有可能产生异常. 1.文件处理 2.内存分配 3.windows资源 4.运行时创建对象和窗体 5.硬件和操作系统冲突 6.网络问题 7.数据 ...
- C# 集合性能比较(代码测试)
using System; using System.Collections; using System.Collections.Generic; using System.Data; using S ...
- Min Stack 解答
Question Design a stack that supports push, pop, top, and retrieving the minimum element in constant ...
- [Ext JS 4] 实战之多选下拉单 (带checkbox)
前言 Ext js 创建一个多选下拉单的方式很简单, 使用Ext.form.ComboBox, 设置 multiSelect 为true 就可以了. 但是如果要在每个下拉之前加上一个checkbox, ...
- Oracle游标动态赋值
1. oracle游标动态赋值的小例子 -- 实现1:动态给游标赋值 -- 实现2:游标用表的rowtype声明,但数据却只配置表一行的某些字段时,遍历游标时需fetch into到精确字段 CREA ...
- Struts2(一)——总体介绍
这篇博客开始将总结一下有关框架的知识,在开发中合适的利用框架会使我们的开发效率大大提高.当今比较流行的开源框架: 关注数据流程的MVC框架 (Struts1/2, WebWork, Spring MV ...
- Vitaliy and Pie(模拟)
Vitaliy and Pie Time Limit:2000MS Memory Limit:262144KB 64bit IO Format:%I64d & %I64u Su ...
- QT_编程基础
简单介绍 Qt是一个由奇趣科技开发的跨平台C++图形用户界面应用程序开发框架.它既能够开发GUI程式,也可用于开发非GUI程式,比方控制台工具和server. Qt是面向对象语言,易于扩展,而且同意组 ...
- Cocos2d-x v3.0正式版尝鲜体验【1】 环境搭建和新建项目
Cocos2d-x v3.0在前天最终公布正式版了,等了大半年最终出来了.一直没去碰之前的3.0各种beta,rc版本号,就想等正式版出来再尝试. 昨天也參加了触控科技在成都举办的沙龙活动.看到作者王 ...