发一个自己基于 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 -1using 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 >= 0){desired = 1 + 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 > 0){desired = expected - 1;atomic_thread_fence(memory_order_release); // syncif(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); // syncif(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 = 5000;void add_job()
{for(int i = 0; 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 = 0; i < count; ++i){read_lock(g_lock);std::cout << g_total << std::endl;;read_unlock(g_lock);}
}int main()
{g_total = 0;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++11 -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。

转载于:https://www.cnblogs.com/JesseFang/p/3521282.html

read write spinlock相关推荐

  1. .net framework 4中SpinLock和lock的区别

    SpinLock,自旋锁.尝试获取该锁的线程持续不断的check是否可以获得.此时线程仍然是激活状态,只是在空转,浪费cpu而已.但是spinlock避免了线程调度和上下文切换,如果锁的时间极短的话, ...

  2. 自己动手实现自旋锁(spinlock)

    大多数的并行程序都需要在底层使用锁机制进行同步,简单来讲,锁无非是一套简单的原语,它们保证程序(或进程)对某一资源的互斥访问来维持数据的一致性,如果没有锁机制作为保证,多个线程可能同时访问某一资源,假 ...

  3. Linux 内核同步(二):自旋锁(Spinlock)

    自旋锁 内核当发生访问资源冲突的时候,可以有两种锁的解决方案选择: 一个是原地等待 一个是挂起当前进程,调度其他进程执行(睡眠) Spinlock 是内核中提供的一种比较常见的锁机制,自旋锁是&quo ...

  4. linux 使用spinlock的配对关系问题

    大家使用spinlock的时候,一般是这么配对: spin_lock---------------------spin_unlock------------------最轻 spin_lock_bh- ...

  5. linux kernel的spinlock在armv7和armv8中的不同

    在armv7中:spin_lock调用了wfe指令,让cpu进入低功耗状态;在spin_unlock中调用了sev指令,让cpu退出低功耗模式; 在armv8中,spin_lock调用了wfe指令,让 ...

  6. linux kernel的spinlock代码导读和分析

    文章目录 一.代码阅读分析 0.spin lock调用流程图 1.再kernel中调用spi_lock()或spin_unlock函数 2.调用raw_spin_lock()和raw_spin_unl ...

  7. 【linux】spinlock 的实现

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

  8. linux 用户态 spinlock,spinlock作用

    Linux系统提供的内核同步机制有很多种. spinlock只是一种选择,并不是所有同步的地方都用spinlock. 通常它适用于对内核(包括模块)的一些全局数据结构的访问. spinlock中所保护 ...

  9. spinlock与linux内核调度的关系

    作者:刘洪涛,华清远见嵌入式学院高级讲师,ARM公司授权ATC讲师. 关于自旋锁用法介绍的文章,已经有很多,但有些细节的地方点的还不够透.我这里就把我个人认为大家容易有疑问的地方拿出来讨论一下.   ...

  10. Pthreads mutex vs Pthreads spinlock

    http://www.searchtb.com/2011/01/pthreads-mutex-vs-pthread-spinlock.html 锁机制(lock) 是多线程编程中最常用的同步机制,用来 ...

最新文章

  1. 点云滤波/分割/关键点提取/配准/识别/重建教程
  2. Linux下的Mongodb部署应用梳理
  3. 心态决定你的人生高度
  4. 【Android】SlidingTabs
  5. 在Eclipse中运行Nutch2.3
  6. Windows Azure Cloud Service (17) Role Endpoint
  7. 新版知识付费系统付费阅读小程序源码知识付费平台
  8. MySQL-----改
  9. python车牌识别_Python-车牌识别
  10. java 读写acr122u_树莓派使用ACR122U读写IC卡
  11. 高德地图开发 —— 获取高德地图开发的 key
  12. mysql错误1197,【MySQL故障处理】 Seconds_Behind_Master= NULL Error_code: 1197
  13. (六十二)基于logistic回归的信用评级和分类模型评估
  14. 企业微信实现扫码登录
  15. 二分法和牛顿迭代法求平方根(Python实现)
  16. 为什么总跳到国内版(cn.bing.com)?New Bing使用全攻略
  17. 源码天空java新闻_Java UpdateRequest类代码示例
  18. 利用Office365进行个税改革员工信息收集
  19. m8 windows android,HTC M8 WP版正式发布 通刷Android和WP8.1
  20. 美前调查人员望政府宽恕斯诺登 称CIA前局长也曾被宽大处理

热门文章

  1. MPU和CPU有什么区别?
  2. Lesson_7 上课笔记_1 ----static关键字和导包
  3. GDI+中发生一般性错误的解决办法 from http://www.cnblogs.com/winzheng/archive/2008/12/23/1360440.html...
  4. 通过OleDB连接方式,访问Access,Excel数据库.
  5. 网站的domain不在首页的原因
  6. RHEL6入门系列之三十,服务管理
  7. 光伏业务爆发 同景新能源与信义光能签署103MW订单
  8. java中io与nio复制文件性能对比
  9. 性能调优:理解Set Statistics IO输出
  10. 设计模式之Adapter