有点让人费解。在用于多线程管理的C#中,我们有互斥锁,也有锁,此外,我还找到了这样的lock RAII实现。
public class ReaderWriterLockSlim_ScopedLockRead : IDisposable
{
ReaderWriterLockSlim m_myLock;
public ReaderWriterLockSlim_ScopedLockRead(ReaderWriterLockSlim myLock)
{
m_myLock = myLock;
m_myLock.EnterReadLock();
}
public void Dispose()
{
m_myLock.ExitReadLock();
}
}
public class ReaderWriterLockSlim_ScopedLockWrite : IDisposable
{
ReaderWriterLockSlim m_myLock;
public ReaderWriterLockSlim_ScopedLockWrite(ReaderWriterLockSlim myLock)
{
m_myLock = myLock;
m_myLock.EnterWriteLock();
}
public void Dispose()
{
m_myLock.ExitWriteLock();
}
}
}
我想了解它们之间的区别,因为对我来说,互斥是第一个多线程管理实现--您需要调用mutex.lock()
,然后不要忘记调用mutex.release()
--通常不太适合调用mutex.release()
,因为在执行过程中可能会出现错误,所以在我看来,它是一种具有相同行为的RAII对象,但是如果在中间得到错误,它就会调用mutex.release()
,一切都很好。
但是我上一次发布的定制工具呢?与lock(obj){}
类似,只是我们有一个不同的read and write
行为,比如在写状态下,有几个线程有可能一个接一个地访问方法和读状态.
我就在这儿吗?
发布于 2019-12-15 01:52:59
因此,对于锁定,重要的是获得的每个锁也被释放(不管它锁定的代码是否有任何异常)。因此,通常情况下,不管您使用什么锁,它看起来都是这样的:
myLock.MyAcquireMethod();
try
{
//...
}
finally
{
myLock.MyReleaseMethod();
}
现在,对于Monitor
在c#
中的锁定机制,它们有一个关键字来使它更容易:lock
。
它基本上将获取和发布封装在一个lock
代码块中。
所以这个:
lock(myObj)
{
//...
}
只是一种更方便的书写方式:
Monitor.Enter(myObj);
try
{
//...
}
finally
{
Monitor.Exit(myObj);
}
遗憾的是,对于其他锁(而且由于Monitor
有它的局限性,我们并不总是想使用它),我们没有这么简单的方法来完成整个工作,并且为了解决这个问题,ReaderWriterLockSlim_ScopedLockRead
包装器实现了为您提供这个try
finally
机制的IDisposable
(using
还保证不管代码运行是否完成或出现异常,Dispose()
都会在IDisposable
上被调用)。
因此,与其:
m_myLock.EnterWriteLock();
try
{
//...
}
finally
{
m_myLock.ExitWriteLock();
}
你现在可以这么做了:
using(new ReaderWriterLockSlim_ScopedLockRead(m_myLock))
{
//...
}
希望这能回答你的问题!
作为奖励,对Monitor
类c#
发出警告。这种锁定机制是线程级上的可重入机构.这意味着允许持有锁的线程多次获取锁(尽管它还必须多次释放锁),这允许您执行以下操作:
private readonly object _myLock = new object();
public void MyLockedMethod1()
{
lock(_myLock)
{
MyLockedMethod2();
}
}
public void MyLockedMethod2()
{
lock(_myLock)
{
//...
}
}
因此,无论是直接调用MyLockedMethod2
还是通过MyLockedMethod1
调用(这可能也需要其他东西的锁),您都可以具有线程安全性。
然而,现在很多人使用async
/await
,其中一个方法可以在另一个线程上继续使用,如果获得它的线程不是释放它的线程,它可以破坏Monitor
,所以我建议您不要使用这样的方法:
public async Task MyLockedMethod()
{
lock(_myLock)
{
await MyAsyncMethod();
}
}
无论如何,如果您想了解更多的话,这里有很多关于这方面的文档。
发布于 2019-12-15 00:41:29
根本不是这样的。读写锁是特定上下文中使用的实现。
它与维基百科在这里描述了它完全一样,不特定于C#或任何其他语言。这只是ReadWriter锁的ReadWriter风格
是一个同步原语,它解决了读者-作者的问题之一。RW锁允许并发访问只读操作,而写操作则需要独占访问.
https://stackoverflow.com/questions/59341902
复制相似问题