那里有更快的那种TMultiReadExclusiveWriteSynchronizer吗?FastCode也许吧?
从Windows Vista开始,Microsoft添加了Slim Reader/Writer锁.它的性能比Delphi 好得多TMultiReadExclusiveWriteSynchronizer.不幸的是,它只存在于Windows Vista及更高版本中,这是很少有客户真正拥有的东西.
据推测,Slim Reader/Writer lock在本机中使用的概念可以在本机Delphi代码中重做 - 但有人做过吗?
我有一种情况,即获取和释放锁定TMultiReadExclusiveWriteSynchronizer(即使没有争用 - 单个线程),导致100%的开销(操作时间加倍).我可以在没有锁定的情况下运行,但是我的类不再是线程安全的.
有更快的TMultiReadExclusiveWriteSynchronizer吗?
注意:如果我使用TCriticalSectioni,只会遭受2%的性能损失(尽管已知关键部分在获取成功时很快,即它是单线程并且没有争用).CS的缺点是我失去了" 多个读者 "的能力.
使用TMultiReadExclusiveWriteSynchronizer相当长的时间在内部BeginRead和EndRead:

然后移植代码以使用Window自己的SlimReaderWriter Lock(其中一些代码重写,因为它不支持递归锁定),并分析了resutls:
TMultiReadExclusiveWriteSynchronizer:每次迭代
10,698 ns 10,697,772,613 ns,迭代1,000,000次
SRWLock:每次迭代
8,802 ns,8,801,678,339 ns,迭代1,000,000次
Omni Reader-Writer lock:每次迭代8,941 ns,
8,940,552,487 ns,迭代1,000,000次
使用SRWLocks(又名Omni的旋转锁)时,性能提高了17%.
现在,我不能永久地切换代码以使用Windows Vista SRWLocks,因为有些客户仍然在Windows XP上.
Slim锁只是小心使用InterlockedCompareExchange功能; 但比我能成功使用更加小心.我 …
delphi multithreading critical-section readerwriterlock readerwriterlockslim
我已经使用了ReaderWriterLockSlim一段时间了,到目前为止它已经满足了我的需求.当我继续微调我的应用程序时,我发现这ReaderWriterLockSlim对我的用例来说有点不理想.
根据文献(和我的经验),它有利于作家而不是读者(即当读者和作家排队时,作家会得到偏好).但是,我需要一个有利于读者的同等学历.我理解这种成分的副作用(特别是作家饥饿问题).
是否有人可以指出的任何生产就绪的等价物?谢谢.
我有一个使用ReaderWriterLockSlim的类,它有一个read方法和一个write方法,它使用read方法来检索要修改的元素.一个简单的例子是:
class FooLocker
{
ReaderWriterLockSlim locker = new ReaderWriterLockSlim();
List<Foo> fooList = new List<Foo>();
public void ChangeFoo(int index, string bar)
{
locker.EnterWriteLock();
try
{
Foo foo = GetFoo(index);
foo.Bar = bar;
}
finally
{
locker.ExitWriteLock();
}
}
public Foo GetFoo(int index)
{
locker.EnterReadLock(); //throws System.Threading.LockRecursionException
try
{
return fooList[index];
}
finally
{
locker.ExitReadLock();
}
}
//snipped code for adding instances etc.
}
Run Code Online (Sandbox Code Playgroud)
如上所述,此代码LockRecursionException在调用时抛出,ChangeFoo()因为在GetFoo()尝试输入读锁定时已经保持写锁定.
我已经检查了文档ReaderWriterLockSlim,我可以LockRecursionPolicy.SupportsRecursion用来允许上面的工作.但是,文档还建议不应将此用于任何新开发,并且只应在升级现有代码时使用.
鉴于此,在write方法可以使用只读方法检索需要修改的事物的情况下,实现相同结果的最佳实践是什么?
要同步对我的属性的访问,我使用ReaderWriterLockSlim类.我使用以下代码以线程安全的方式访问我的属性.
public class SomeClass
{
public readonly ReaderWriterLockSlim SyncObj = new ReaderWriterLockSlim();
public string AProperty
{
get
{
if (SyncObj.IsReadLockHeld)
return ComplexGetterMethod();
SyncObj.EnterReadLock();
try
{
return ComplexGetterMethod();
}
finally
{
SyncObj.ExitReadLock();
}
}
set
{
if (SyncObj.IsWriteLockHeld)
ComplexSetterMethod(value);
else
{
SyncObj.EnterWriteLock();
ComplexSetterMethod(value);
SyncObj.ExitWriteLock();
}
}
}
// more properties here ...
private string ComplexGetterMethod()
{
// This method is not thread-safe and reads
// multiple values, calculates stuff, ect.
}
private void ComplexSetterMethod(string newValue)
{
// This method …Run Code Online (Sandbox Code Playgroud) 我有一个主要设计为POCO类的类,各种线程和任务可以读取其值,只有其他只偶尔更新这些值.这似乎是ReaderWriterLockSlim的理想场景.
问题是,在类中,如果属性需要是线程安全的,如果属性是bool,那是否过度杀伤?如果它是一个int会发生什么?约会时间?
public class MyClass
{
private bool _theValue = false;
private ReaderWriterLockSlim _theValueLock = new ReaderWriterLockSlim();
public bool TheValue
{
get
{
bool returnVal = false;
try
{
_theValueLock.EnterReadLock();
returnVal = _theValue;
}
finally
{ _theValueLock.ExitReadLock(); }
return returnVal;
}
set
{
try
{
_theValueLock.EnterWriteLock();
_theValue = value;
}
finally
{ _theValueLock.ExitWriteLock(); }
}
}
}
Run Code Online (Sandbox Code Playgroud)
所有这些代码都是矫枉过正的,而且简单......
public bool TheValue { get; set; }
Run Code Online (Sandbox Code Playgroud)
......会足够吗?因为Type是bool,安全吗?如果是的话,什么时候变得不安全?字节?诠释?约会时间?
编辑
我的基本架构是具有此类存储状态.也许有一个服务负责对这个类进行写操作.所有其他类都可以根据此状态数据读取和执行其逻辑.我会尽力确保所有数据都是一致的,但如下所述,我主要担心的是数据的原子性和危险性.
结论
感谢大家的回应,一切都很有价值.我主要担心的是写入/读取的原子性(即担心痉挛).对于.NET平台,如果有问题的变量是一个小于4个字节的内置值类型,则读取和写入是原子的(例如,short和int很好,long和double不是).
我喜欢C#中的快捷方式lock(myLock){ /* do stuff */}.是否有读/写锁的等价物?(特别是ReaderWriterLockSlim.)现在,我使用以下自定义方法,我认为它有效,但有点烦人,因为我必须将我的操作作为匿名函数传递,我宁愿使用标准锁定机制,如果可能的话.
void bool DoWithWriteLock(ReaderWriterLockSlim RWLock, int TimeOut, Action Fn)
{
bool holdingLock = false;
try
{
if (RWLock.TryEnterWriteLock(TimeOut))
{
holdingLock = true;
Fn();
}
}
finally
{
if (holdingLock)
{
RWLock.ExitWriteLock();
}
}
return holdingLock;
}
Run Code Online (Sandbox Code Playgroud) 我正在ReaderWriterLockSlim用来保护一些操作.我想赞成读者而不是作家,这样当读者长时间持有锁并且作家试图获得写锁时,未来的读者也不会被作者的尝试所阻挡(如果是这样的话会发生这种情况.作家被封锁了lock.EnterWriteLock()).
为此,我虽然编写器可以TryEnterWriteLock在循环中使用短暂的超时,以便后续的读者仍然能够获得读锁定而编写者不能.然而,令我惊讶的是,我发现一个不成功的呼叫TryEnterWriteLock改变了锁的状态,无论如何阻止了未来的读者.概念证明代码:
System.Threading.ReaderWriterLockSlim myLock = new System.Threading.ReaderWriterLockSlim(System.Threading.LockRecursionPolicy.NoRecursion);
System.Threading.Thread t1 = new System.Threading.Thread(() =>
{
Console.WriteLine("T1:{0}: entering read lock...", DateTime.Now);
myLock.EnterReadLock();
Console.WriteLine("T1:{0}: ...entered read lock.", DateTime.Now);
System.Threading.Thread.Sleep(10000);
});
System.Threading.Thread t2 = new System.Threading.Thread(() =>
{
System.Threading.Thread.Sleep(1000);
while (true)
{
Console.WriteLine("T2:{0}: try-entering write lock...", DateTime.Now);
bool result = myLock.TryEnterWriteLock(TimeSpan.FromMilliseconds(1500));
Console.WriteLine("T2:{0}: ...try-entered write lock, result={1}.", DateTime.Now, result);
if (result)
{
// Got it!
break;
}
System.Threading.Thread.Yield();
}
System.Threading.Thread.Sleep(9000);
});
System.Threading.Thread t3 = new System.Threading.Thread(() => …Run Code Online (Sandbox Code Playgroud) 我得到了这个异常
读取锁定被释放而没有被释放.
在System.Threading.ReaderWriterLockSlim.ExitReadLock()at .. GetBreed(String)
下面是访问锁的代码中唯一的位置.如您所见,没有递归.我无法理解如何发生此异常.
static readonly Dictionary<string, BreedOfDog> Breeds
= new Dictionary<string,BreedOfDog>();
static BreedOfDog GetBreed(string name)
{
try
{
rwLock.EnterReadLock();
BreedOfDog bd;
if (Breeds.TryGetValue(name, out bd))
{
return bd;
}
}
finally
{
rwLock.ExitReadLock();
}
try
{
rwLock.EnterWriteLock();
BreedOfDog bd;
//make sure it hasn't been added in the interim
if (Breeds.TryGetValue(t, out bd)
{
return bd;
}
bd = new BreedOfDog(name); //expensive to fetch all the data needed to run the constructor, hence the caching
Breeds[name] = bd; …Run Code Online (Sandbox Code Playgroud) 我们有项目目标.NET 2.0 RTM(是的,它应该是.NET 2.0 RTM,我们有一些正统的客户端).而我只是想知道ReaderWriterLock的缺点是什么?为什么每个人都说"不要使用它,尝试使用其他类似lock声明" 这么糟糕?如果我们可以使用.NET 3.5,我肯定会使用ReaderWriterLockSlim,但ReaderWriterLock我对所有这些来自各地的警告都有点害怕.有人测量过表现还是其他什么?如果存在一些性能问题,我们可以在哪些有效负载下遇到它们?
我们在ReaderWriterLock主要目的方面有一个经典的情况,即多次读取和很少写入.使用lock语句会阻止所有读者.也许对我们来说这不是一个可怕的问题,但如果我可以使用,ReaderWriterLock我会更满意.国际海事组织介绍几台显示器确实是一个非常糟糕的主意.
.net c# multithreading readerwriterlock readerwriterlockslim
MSDN文档和许多使用ReaderWriterLockSlim类的示例建议使用以下模式:
cacheLock.EnterWriteLock();
try
{
//Do something
}
finally
{
cacheLock.ExitWriteLock();
}
Run Code Online (Sandbox Code Playgroud)
但我很好奇它是否完全安全.获取锁之后是否可能发生某些异常,但是在try语句之前锁定被锁定状态?最明显的候选人是ThreadAbortException.我知道这种情况的可能性非常小,但后果极其糟糕 - 所以我认为值得考虑一下.我不相信编译器理解这种模式并阻止处理器在try语句之前中断线程.
如果理论上有可能这个代码不安全,有没有办法让它更安全?