c# – 同时获取多个线程同步锁

c# – 同时获取多个线程同步锁,第1张

概述我们假设以下代码在我的应用程序中以类似的方式使用: //-------------------------------------void UseAllResources (){ bool bSuccess1 = false; bool bSuccess2 = false; try { bSuccess1 = Monitor::TryEnter (oResource1, 我们假设以下代码在我的应用程序中以类似的方式使用:

//-------------------------------------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# – 同时获取多个线程同步锁所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址:https://54852.com/langs/1226932.html

(0)
打赏 微信扫一扫微信扫一扫 支付宝扫一扫支付宝扫一扫
上一篇 2022-06-05
下一篇2022-06-05

发表评论

登录后才能评论

评论列表(0条)

    保存