我常用的 C++ 读写锁
来源:互联网 发布:百度贴吧衰落知乎 编辑:程序博客网 时间:2024/06/05 05:35
锁操作是为了线程安全,下面写一个我常用的 C++ 自旋锁,简单高效。
#include <unistd.h>#include <fcntl.h>#include <stdio.h>#include <sys/time.h>#include <errno.h>#include <stdio.h>#include <unistd.h>#include <sys/types.h>template<typename T>class RSpinLock{ public: RSpinLock( T * addr ) : m_addr(addr) { while( true ) { T old = * m_addr; old &= (T)~1; if( __sync_bool_compare_and_swap( m_addr, old, old | 2 ) ) //set reader { __sync_fetch_and_add( m_addr, 4 ); //add a reader break; } } } ~RSpinLock( ) { __sync_fetch_and_sub( m_addr, 4 ); __sync_bool_compare_and_swap( m_addr, 2, 0 ); //clear reader } private: T * m_addr;}; template<typename T>class WSpinLock{ public: WSpinLock( T * addr ) : m_addr(addr) { while( !__sync_bool_compare_and_swap( m_addr, 0, 1 ) ); } ~WSpinLock( ) { *m_addr = 0; } private: T * m_addr;};
写自旋锁中的 __sync_bool_compare_and_swap(m_addr, 0, 1)
函数表示当调用构造函数时将 m_addr
指向的值为 0 时,将其交换为 1 并返回 ture
,相当于某个进程拿到了锁。
当另外的进程调用构造函数时,由于 m_addr
已经指向 1,__sync_bool_compare_and_swap(m_addr, 0, 1)
则返回 false
,那么这个进程就被锁在了 while 循环中。直到拿到锁的进程调用析构函数将 m_addr
指向的值再次修改为 0,释放调锁。
需要上锁时直接在代码块中构造 WSpinLock 对象即可。
{ WSpinLock<uint32_t> locker( &m_bf_meta.Ptr()->tItemMeta[index].iLock ); /* 上锁后的操作 */}// 跳出代码块后,自动调用 locker 析构函数,释放掉锁
读自旋锁测试代码如下:
#include "RWSpinLock.h"#include <stdio.h>int main(){ char x = 0; { RSpinLock<char> l1(&x); { RSpinLock<char> l2(&x); { RSpinLock<char> l3(&x); printf("%d\n", x); } printf("%d\n", x); } printf("%d\n", x); } printf("%d\n", x); return 0;}
0 0
- 我常用的 C++ 读写锁
- [我眼中的C#]文件读写操作
- 常用的C/C++文本文件的读写函数
- C语言中常用的文件读写方法(一)
- C语言中常用的文件读写方法(二)
- 常用的读写API
- 数据库读写锁的实现(C++)
- C文件的读写
- C文件的读写
- 【C#】txt的读写
- C#_文件读写常用类介绍
- C++_文本文件读写常用代码
- C++_文本文件读写常用代码
- C++_文本文件读写常用代码
- C语言常用文件读写函数记录
- 常用的文件读写函数
- [C++]一个我比较常用的循环双向链表
- C#:读写简单的文本文件
- HDU 5748 BestCoder Round #84 Bellovin (LIS)(树状数组)
- 家谱处理
- POJ 2752 Seek the Name, Seek the Fame (kmp next数组运用)
- 常用算法时间复杂度和空间复杂度表
- 项目报Unable to process Jar entry [...........] from .........
- 我常用的 C++ 读写锁
- POJ2492 A Bug's Life 并查集
- 图形界面(GUI)
- R语言数据基本类型与操作
- HDU 5727 枚举环排列+二分图匹配/状压
- Oracle 11g 默认用户名和密码不正确
- 文章标题
- 第八章 互斥型信号量管理
- tomcat超时启动Server Tomcat v7.0 Server at localhost was unable to start within 45 seconds. If the serve