跨平台轻量级读写锁
2015-07-21 16:41 哦万里云 阅读(448) 评论(0) 编辑 收藏 举报锁的数据结构足够简单: volatile long;
将long的最高位存放写锁标志,低24位作为读锁计数;
写锁的实现:
1.加锁时,等待long位0时设置写锁标志,用原子操作实现。可以保证加锁前没有任何人获得读锁或写锁;
2.解锁时,去掉写锁标志;
读锁的实现:
1.加锁时,首先增加读锁计数,于是释放前任何写锁都会失败。然后等待写锁释放(如果有);
2.解锁时,减少读锁计数;
保证,任意时刻
1.加了一个写锁(没有任何读锁)
2.或者同时加多个读锁(没有任何写锁)
头文件;
#ifndef _MY_ATOMIC_H_ #define _MY_ATOMIC_H_ class ReadLock { public: ReadLock(volatile long & lock); ~ReadLock(); private: ReadLock(const ReadLock & ); ReadLock & operator = (const ReadLock & ); private: volatile long & m_lock; }; class WriteLock { public: WriteLock(volatile long & lock); ~WriteLock(); private: WriteLock(const WriteLock & ); WriteLock & operator = (const WriteLock & ); private: volatile long & m_lock; }; #endif
头文件;
#include "Atomic.h" static union{ char c[4];unsigned long myLong;} test_union = { { 'L','?','?','B'} }; #define ENDIANNESS ((char)test_union.myLong) void MyLockedAdd(volatile long & dst,long val) { #ifdef WIN32 InterlockedExchangeAdd(&dst,val); #else __sync_add_and_fetch(&dst,val); #endif } bool MyLockedCompareSwap(volatile long & dst,long val,long cmp) { #ifdef WIN32 return cmp == InterlockedCompareExchange(&dst,val,cmp); #else return __sync_bool_compare_and_swap (&dst,cmp,val); #endif } const long WRITE_LOCK_VALUE = 1<<24; ReadLock::ReadLock(volatile long & lock):m_lock(lock) { MyLockedAdd(m_lock,1); volatile char * pWL = (volatile char *)&m_lock; if(ENDIANNESS == 'L') pWL += 3; for(;*pWL;) ; } ReadLock::~ReadLock() { MyLockedAdd(m_lock,-1); } WriteLock::WriteLock(volatile long & lock):m_lock(lock) { while(!MyLockedCompareSwap(m_lock,WRITE_LOCK_VALUE,0)) ; } WriteLock::~WriteLock() { MyLockedAdd(m_lock,-WRITE_LOCK_VALUE); }