科技行者

行者学院 转型私董会 科技行者专题报道 网红大战科技行者

知识库

知识库 安全导航

至顶网软件频道基础软件C#多线程编程实例实战(2)

C#多线程编程实例实战(2)

  • 扫一扫
    分享文章到微信

  • 扫一扫
    关注官方公众号
    至顶头条

释放阅读锁的函数原型为:public void ReleaseReaderLock()。函数定义如下

来源:soft6 2008年5月16日

关键字: 编程 多线程 C# Windows

  • 评论
  • 分享微博
  • 分享邮件

释放阅读锁的函数原型为: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领域最新产品与技术信息,那么订阅至顶网技术邮件将是您的最佳途径之一。

    重磅专题
    往期文章
    最新文章