扫一扫
分享文章到微信
扫一扫
关注官方公众号
至顶头条
释放阅读锁的函数原型为:public void ReleaseReaderLock()。函数定义如下:
public void ReleaseReaderLock()
{
System.LocalDataStoreSlot slot = Thread.GetNamedDataSlot(m_strThreadSlotName );
LockFlags flag = (LockFlags)Thread.GetData( slot );
if( flag == LockFlags.None )
{ return;
}
bool bReader = true; switch( flag )
{
case LockFlags.None:
break;
case LockFlags.Writer:
bReader = false;
break;
}
if( !bReader )
return;
Thread.SetData( slot, LockFlags.None );
m_mutex.WaitOne();
AutoResetEvent autoresetevent = null;
this.m_nActive --;
if( this.m_nActive == 0 )
{ if( this.m_nWaitingReaders > 0 )
{
m_nActive ++ ;
m_nWaitingReaders --;
autoresetevent = this.m_aeReaders;
}
else if( this.m_nWaitingWriters > 0)
{
m_nWaitingWriters--;
m_nActive --;
autoresetevent = this.m_aeWriters ;
} }
m_mutex.ReleaseMutex();
if( autoresetevent != null )
autoresetevent.Set();
}
释放阅读锁时,首先判断当前线程是否拥有阅读锁(通过线程局部存储的标志),然后判断是否有等待的阅读线程,如果有,先将当前活动线程加1,等待阅读线程数目减1,然后置事件为有信号。如果没有等待的阅读线程,判断是否有等待的写入线程,如果有则活动线程数目减1,等待的写入线程数目减1。释放写入锁与释放阅读锁的过程基本一致,可以参看源代码。
注意在程序中,释放锁时,只会唤醒一个阅读程序,这是因为使用AutoResetEvent的原历,读者可自行将其改成ManualResetEvent,同时唤醒多个阅读程序,此时应令m_nActive等于整个等待的阅读线程数目。
测试
测试程序取自.Net FrameSDK中的一个例子,只是稍做修改。测试程序如下,
using System;
using System.Threading;
using MyThreading;
class Resource {
myReaderWriterLock rwl = new myReaderWriterLock();
public void Read(Int32 threadNum) {
rwl.AcquireReaderLock(Timeout.Infinite);
try { Console.WriteLine("Start Resource reading (Thread={0})", threadNum);
Thread.Sleep(250);
Console.WriteLine("Stop Resource reading (Thread={0})", threadNum);
}
finally { rwl.ReleaseReaderLock();
} }
public void Write(Int32 threadNum) {
rwl.AcquireWriterLock(Timeout.Infinite);
try {
Console.WriteLine("Start Resource writing (Thread={0})", threadNum);
Thread.Sleep(750);
Console.WriteLine("Stop Resource writing (Thread={0})", threadNum);
}
finally { rwl.ReleaseWriterLock();
} }
}
class App {
static Int32 numAsyncOps = 20;
static AutoResetEvent asyncOpsAreDone = new AutoResetEvent(false);
static Resource res = new Resource();
public static void Main() {
for (Int32 threadNum = 0; threadNum < 20; threadNum++) {
ThreadPool.QueueUserWorkItem(new WaitCallback(UpdateResource), threadNum);
}
asyncOpsAreDone.WaitOne();
Console.WriteLine("All operations have completed.");
Console.ReadLine();
}
// The callback method''s signature MUST match that of a System.Threading.TimerCallback
// delegate (it takes an Object parameter and returns void)
static void UpdateResource(Object state) {
Int32 threadNum = (Int32) state;
if ((threadNum % 2) != 0) res.Read(threadNum);
else res.Write(threadNum);
if (Interlocked.Decrement(ref numAsyncOps) == 0)
asyncOpsAreDone.Set();
}
}
如果您非常迫切的想了解IT领域最新产品与技术信息,那么订阅至顶网技术邮件将是您的最佳途径之一。
现场直击|2021世界人工智能大会
直击5G创新地带,就在2021MWC上海
5G已至 转型当时——服务提供商如何把握转型的绝佳时机
寻找自己的Flag
华为开发者大会2020(Cloud)- 科技行者