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 ...
随机推荐
- Keil中Memory Model和Code Rom Size说明
C51中定义变量时如果省略存储器类型,Keil C51编译系统则会按编译模式SMALL.COMPACT和LARGE所规定的默认存储器类型去指定变量的存储区域,无论什么存储模式都可以声明变量在任何的80 ...
- 十大面试问题解惑,秒杀一切HR、技术面试
最能体现求职者能力的就是面试,能不能拿到Offer,取决于你面试时的表现,只有有准备才能在面试过程中游刃有余.小编收集了10个面试官最爱提的问题,虽然题目千变万化,但是万变不离其宗,只要掌握了答题的技 ...
- WPF控件中可以用来记录数据用的属性总结
今天遇到一个问题需要为每个控件tooltip根据不同情况显示多组数据,于是需要用到控件的某个属性暂存这个数据.好吧,现在我找到了3个属性可用,给自己做个备忘. 1.Tag 这个属性是object类型 ...
- Vitamio视频播放
activity代码 package com.hck.player.ui; import io.vov.utils.StringUtils; import io.vov.vitamio.LibsChe ...
- java 防止sql注入的方法(非原创)
一.SQL注入简介 SQL注入是比较常见的网络攻击方式之一,它不是利用操作系统的BUG来实现攻击,而是针对程序员编程时的疏忽,通过SQL语句,实现无帐号登录,甚至篡改数据库. 二.SQ ...
- socketpair的使用
socketpair函数概要例如以下:#include <sys/types.h>#include <sys/socket.h>int socketpair(int domai ...
- Maven 工程下 Spring MVC 站点配置 (一)
最近,查找一些具体资料时,虽然会有很多,但是系统的却很少,尤其是对maven 下 spring mvc 站点搭建的配置,总是说的很多但让新手一目了然的步骤却少之又少. 对此闲暇时整理了一下,做了一套较 ...
- Serializable在C#中的作用——.net中的对象序列化
序列化是指将对象实例的状态存储到存储媒体的过程,在此过程中,先将对象的公共字段和私有字段以及类的名称(包括类所在的程序集)转换为字节流,然后再把字节流写入数据流,在随后对对象进行反序列化时,将创建出与 ...
- 六步实现Spring.NET 与 NHibernate 的整合
最近刚完成一个项目,其中对数据库的架构用到的是Spring.NET 与 NHibernate相结合的产物.对于这两项技术,我自己也不是太熟悉,不过好在网上有很多关于这方面的介绍文档,在这里就不多说了. ...
- QT-利用C++仿制windown自带的记事本程序V1.0
下班无事, 发现QT还是很好用的, 就仿制windows的记事本做了一个,未彻底DEBUG, 先拿来分享下. windows记事本大概是这样的: 大概分为以下几步: 1. 界面用QT代码写,即可, Q ...