C# 这种ReaderWriterLockSlim锁定模式看起来合适吗?
我一直使用它来同步读/写,到目前为止,它工作得相当好 我有一个对象集合,读/写锁保存在C# 这种ReaderWriterLockSlim锁定模式看起来合适吗?,c#,thread-safety,readerwriterlockslim,C#,Thread Safety,Readerwriterlockslim,我一直使用它来同步读/写,到目前为止,它工作得相当好 我有一个对象集合,读/写锁保存在字典中。我有一个场景,需要以原子方式获取多个读锁。我确信我没有任何代码允许一个线程尝试同时持有多个写锁,这使我认为下面的代码可以正常工作 如果我用写锁而不是读锁来尝试下面的方法,我几乎可以肯定我会以死锁告终,除非我能确保锁总是以相同的顺序发生(在我的情况下我不能) 是否有人认为此代码存在以下问题: 在其他地方,不允许持有写锁的线程持有任何其他锁(读或写) 多个线程可以同时持有任意数量的读锁 有什么想法吗 pub
字典中。我有一个场景,需要以原子方式获取多个读锁。我确信我没有任何代码允许一个线程尝试同时持有多个写锁,这使我认为下面的代码可以正常工作
如果我用写锁而不是读锁来尝试下面的方法,我几乎可以肯定我会以死锁告终,除非我能确保锁总是以相同的顺序发生(在我的情况下我不能)
是否有人认为此代码存在以下问题:
在其他地方,不允许持有写锁的线程持有任何其他锁(读或写)
多个线程可以同时持有任意数量的读锁
有什么想法吗
public void WithReaderLocksForItemsNamed(string[] itemNames, Action action)
{
// this gets locks for the items specified from my internation dictionary
ReaderWriterLockSlim[ ] locks = LocksForItemsNamed( itemNames ) ;
try
{
foreach( var @lock in locks )
{
@lock.EnterReadLock( ) ;
}
action( ) ;
}
finally
{
foreach( var @lock in locks )
{
if (@lock.IsReadLockHeld)
{
@lock.ExitReadLock( ) ;
}
}
}
}
它看起来还可以,但您可能需要对方法本身设置一个重入锁,当然,您需要在其中迭代源列表以获取锁。它看起来还可以,但您可能需要对方法本身设置重入锁,当然,一个迭代源代码列表以获得锁的问题。这是一个老问题,但我认为用最终的解决方案更新它还是不错的。虽然我从来没有遇到过上述问题,但我采用了谨慎的做法,按照与获得锁相反的顺序退出锁。因此,最终代码如下所示:
public void WithReaderLocksForItemsNamed(string[] itemNames, Action action)
{
// this gets locks for the items specified from my internation dictionary
ReaderWriterLockSlim[ ] locks = LocksForItemsNamed( itemNames ) ;
try
{
foreach( var @lock in locks )
{
@lock.EnterReadLock( ) ;
}
action( ) ;
}
finally
{
foreach( var @lock in locks.Reverse() )
{
if (@lock.IsReadLockHeld)
{
@lock.ExitReadLock( ) ;
}
}
}
}
这是一个老问题,但我认为用最终的解决方案来更新它还是不错的。虽然我从来没有遇到过上述问题,但我采用了谨慎的做法,按照与获得锁相反的顺序退出锁。因此,最终代码如下所示:
public void WithReaderLocksForItemsNamed(string[] itemNames, Action action)
{
// this gets locks for the items specified from my internation dictionary
ReaderWriterLockSlim[ ] locks = LocksForItemsNamed( itemNames ) ;
try
{
foreach( var @lock in locks )
{
@lock.EnterReadLock( ) ;
}
action( ) ;
}
finally
{
foreach( var @lock in locks.Reverse() )
{
if (@lock.IsReadLockHeld)
{
@lock.ExitReadLock( ) ;
}
}
}
}
您能解释一下为什么对同一个操作使用多个锁吗?该操作依赖于所有项在执行时保持不变。SQL世界中的一个例子是创建一个连接两个表的视图,我需要确保操作不会失败,因为在创建视图的过程中,引用的一个表正在被更改。这完全没关系,如果表在事件发生后立即更改……使用多个锁总是会带来死锁的好机会。这就是ReaderWriterLockSlim存在的原因——解决同时使用两个锁来保护资源的问题。你用锁保护什么样的资源?你的程序是多线程的吗?那么你的代码到底有什么问题?您是否遇到死锁?@Scott,该功能在概念上类似于我提到的SQL视图示例。需要在确保操作所依赖的资源保持不变(因此读取锁)的情况下执行操作。该程序本身并不是大规模多线程的,但有一些事件(从外部触发)可能会导致资源被删除和重新创建。我想确保我的操作在这些更新期间不会失败。请解释为什么对同一操作使用多个锁?该操作依赖于所有项在执行时保持不变。SQL世界中的一个例子是创建一个连接两个表的视图,我需要确保操作不会失败,因为在创建视图的过程中,引用的一个表正在被更改。这完全没关系,如果表在事件发生后立即更改……使用多个锁总是会带来死锁的好机会。这就是ReaderWriterLockSlim存在的原因——解决同时使用两个锁来保护资源的问题。你用锁保护什么样的资源?你的程序是多线程的吗?那么你的代码到底有什么问题?您是否遇到死锁?@Scott,该功能在概念上类似于我提到的SQL视图示例。需要在确保操作所依赖的资源保持不变(因此读取锁)的情况下执行操作。该程序本身并不是大规模多线程的,但有一些事件(从外部触发)可能会导致资源被删除和重新创建。我想确保我的操作在这些更新期间不会失败。