ReaderWriter无锁实现

时间:2013-09-27 11:27:57

标签: lock-free readerwriterlock

我想使用volatile值实现一个简单的多读取器/单写入器锁。

虽然_InterlockedXXX提供了完整的栅栏屏障,如果我是对的,也是“volatile”关键字,我想知道可能的缺陷和改进。我没有获取/发布语义的经验。

我的代码:

BOOL TryAcquireShared(LONG volatile *lpnValue) 
{ 
  LONG initVal; 

  do 
  { 
    initVal = *lpnValue; 
    if (initVal == 0x80000000L) 
      return FALSE; //a writer is active 
  } 
  while (_InterlockedCompareExchange(lpnValue, initVal+1, initVal) != initVal); 
  return TRUE; 
} 

VOID ReleaseShared(LONG volatile *lpnValue) 
{ 
  LONG initVal, newVal; 

  do 
  { 
    initVal = *lpnValue; 
    newVal = (initVal & 0x80000000L) | ((initVal & 0x7FFFFFFFL) - 1); 
  } 
  while (_InterlockedCompareExchange(lpnValue, newVal, initVal) != initVal); 
  return; 
} 

BOOL TryAcquireExclusive(LONG volatile *lpnValue) 
{ 
  LONG i, initVal, newVal; 

  do 
  { 
    initVal = *lpnValue; 
    if ((initVal & 0x80000000L) != 0) 
      return FALSE; //another writer is active or waiting 
  } 
  while (_InterlockedCompareExchange(lpnValue, initVal | 0x80000000L, initVal) != initVal); 
  //wait until no readers 
  while ((*lpnValue & 0x7FFFFFFFL) != 0) 
    ::Sleep(1); 
  return TRUE; 
} 

VOID ReleaseExclusive(LONG volatile *lpnValue) 
{ 
  _InterlockedExchange(lpnValue, 0); 
  return; 
} 

另外,如果您知道可以处理此问题的库,请告诉我。

1 个答案:

答案 0 :(得分:0)

  • TryAcquireShared应该在增加之前检查* lpnValue是否为0x7FFFFFFFL。
  • ReleaseShared应断言* lpnValue没有设置0x80000000L位,而是试图保留它。如果要释放共享锁,则不应存在独占锁。
  • TryAcquireExclusive只应在设置0x80000000L位之前检查* lpnValue是否为零。
  • aquire分享和aquire exclusive应该每隔一定数量的旋转进行一次Sleep(1)调用。
  • 我不了解TryAcquireExclusive中的以下部分。如果你有一个独家锁,为什么还要等读者?

    while((* lpnValue& 0x7FFFFFFFL)!= 0)     ::睡眠(1);