
//-------------------------------------voID UseAllResources (){ bool bSuccess1 = false; bool bSuccess2 = false; try { bSuccess1 = Monitor::TryEnter (oResource1,msc_iTimeoutMonitor); if (!bSuccess1) return; bSuccess2 = Monitor::TryEnter (oResource2,msc_iTimeoutMonitor); if (!bSuccess2) return; // work on oResource1 and oResource2 } finally { if (bSuccess2) Monitor::Exit (oResource2); if (bSuccess1) Monitor::Exit (oResource1); }}//-------------------------------------voID UseResource1 (){ bool bSuccess = false; try { bSuccess = Monitor::TryEnter (oResource1,msc_iTimeoutMonitor); if (!bSuccess) return; // work on oResource1 } finally { if (bSuccess) Monitor::Exit (oResource1); }}//-------------------------------------voID UseResource2 (){ same like UseResource1(),but using oResource2} 这些函数可能随时被不同的线程调用.
可能会发生这种情况
(超时为500毫秒)
@t = 0ms,线程B正在执行UseResource2(),需要400ms,
@t = 100ms,线程Z调用UseAllResources(),对oResource1进行锁定,并且必须等待oResource2上的锁定,
@t = 200ms,线程A正在调用UseResource1()并且必须等待oResource1上的锁定,这是由线程Z占用的,
@t = 400ms,线程B完成,线程Z锁定oResource2并开始工作,
@t = 700ms,线程A超时,虽然它只需要50ms并且可以在线程Z仍在等待时工作.
我宁愿让线程Z失败,如果有的话,因为超时应该是所有锁的整体值.
我可以同时开始获取多个锁吗?
解决方法 解决方案可能是使用readerwriterlockslim类.以下代码在构造函数中包装了一个函数(您要完成的工作).或者,您可以将函数移动到DoWork方法以更改访问资源的方式.LockedResource implmentation
class LockedResource{ public delegate voID RefAction(); readerwriterlockslim resourceLock; public LockedResource() { //Warning: SupportsRecursion is risky,you should remove support for recursive whenever possible resourceLock = new readerwriterlockslim(LockRecursionPolicy.SupportsRecursion); } public bool DoWork(RefAction work,string threadname,int timeout = -1) { try { if (resourceLock.TryEnterWriteLock(timeout)) { if (work != null) { work(); } } else { Console.Writeline("Lock time out on thread {0}",threadname); } } finally { Console.Writeline("{0} releasing resource",threadname); if(resourceLock.IsWriteLockHeld) { resourceLock.ExitWriteLock(); } } return false; }} 样本用法
static voID Main(string[] args){ object oResouce1 = "-"; object oResouce2 = "-"; LockedResource lock1 = new LockedResource(); LockedResource lock2 = new LockedResource(); //the event wait handles is not required,only used to block thread so that resource values can be printed out at the end of the program var h1 = new EventWaitHandle(false,EventresetMode.Manualreset); var h2 = new EventWaitHandle(false,EventresetMode.Manualreset); var h3 = new EventWaitHandle(false,EventresetMode.Manualreset); WaitHandle[] waitHandles = { h1,h2,h3 }; var t1 = new Thread(() => { lock1.DoWork(() => { oResouce1 = "1"; Console.Writeline("Resource 1 set to 1"); },"T1"); h1.Set(); }); var t2 = new Thread(() => { lock2.DoWork(() => { oResouce2 = "2"; Console.Writeline("Resource 2 set to 2"); Thread.Sleep(10000); },"T2"); h2.Set(); }); var t3 = new Thread(() => { lock1.DoWork(() => { lock2.DoWork(() => { oResouce1 = "3"; Console.Writeline("Resource 1 set to 3"); oResouce2 = "3"; Console.Writeline("Resource 2 set to 3"); },"T3",1000); h3.Set(); },"T3"); }); t1.Start(); t2.Start(); t3.Start(); WaitHandle.WaitAll(waitHandles); Console.Writeline("Resource 1 is {0}",oResouce1); Console.Writeline("Resource 2 is {0}",oResouce2); Console.Readline();} 产量
总结Resource 1 set to 1 Resource 2 set to 2 T1 releasing resource Lock time out on thread T3 T3 releasing resource T3 releasing resource T2 releasing resource Resource 1 is 1 Resource 2 is 2
以上是内存溢出为你收集整理的c# – 同时获取多个线程同步锁全部内容,希望文章能够帮你解决c# – 同时获取多个线程同步锁所遇到的程序开发问题。
如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。
欢迎分享,转载请注明来源:内存溢出
微信扫一扫
支付宝扫一扫
评论列表(0条)