gpt4 book ai didi

c# - ReaderWriterLockSlim 什么时候比简单的锁更好?

转载 作者:IT王子 更新时间:2023-10-29 03:41:14 26 4
gpt4 key购买 nike

我正在使用这段代码在 ReaderWriterLock 上做一个非常愚蠢的基准测试,其中读取的频率是写入的 4 倍:

class Program
{
static void Main()
{
ISynchro[] test = { new Locked(), new RWLocked() };

Stopwatch sw = new Stopwatch();

foreach ( var isynchro in test )
{
sw.Reset();
sw.Start();
Thread w1 = new Thread( new ParameterizedThreadStart( WriteThread ) );
w1.Start( isynchro );

Thread w2 = new Thread( new ParameterizedThreadStart( WriteThread ) );
w2.Start( isynchro );

Thread r1 = new Thread( new ParameterizedThreadStart( ReadThread ) );
r1.Start( isynchro );

Thread r2 = new Thread( new ParameterizedThreadStart( ReadThread ) );
r2.Start( isynchro );

w1.Join();
w2.Join();
r1.Join();
r2.Join();
sw.Stop();

Console.WriteLine( isynchro.ToString() + ": " + sw.ElapsedMilliseconds.ToString() + "ms." );
}

Console.WriteLine( "End" );
Console.ReadKey( true );
}

static void ReadThread(Object o)
{
ISynchro synchro = (ISynchro)o;

for ( int i = 0; i < 500; i++ )
{
Int32? value = synchro.Get( i );
Thread.Sleep( 50 );
}
}

static void WriteThread( Object o )
{
ISynchro synchro = (ISynchro)o;

for ( int i = 0; i < 125; i++ )
{
synchro.Add( i );
Thread.Sleep( 200 );
}
}

}

interface ISynchro
{
void Add( Int32 value );
Int32? Get( Int32 index );
}

class Locked:List<Int32>, ISynchro
{
readonly Object locker = new object();

#region ISynchro Members

public new void Add( int value )
{
lock ( locker )
base.Add( value );
}

public int? Get( int index )
{
lock ( locker )
{
if ( this.Count <= index )
return null;
return this[ index ];
}
}

#endregion
public override string ToString()
{
return "Locked";
}
}

class RWLocked : List<Int32>, ISynchro
{
ReaderWriterLockSlim locker = new ReaderWriterLockSlim();

#region ISynchro Members

public new void Add( int value )
{
try
{
locker.EnterWriteLock();
base.Add( value );
}
finally
{
locker.ExitWriteLock();
}
}

public int? Get( int index )
{
try
{
locker.EnterReadLock();
if ( this.Count <= index )
return null;
return this[ index ];
}
finally
{
locker.ExitReadLock();
}
}

#endregion

public override string ToString()
{
return "RW Locked";
}
}

但我知道两者的表现大致相同:

Locked: 25003ms.
RW Locked: 25002ms.
End

即使读取频率是写入频率的 20 倍,性能仍然(几乎)相同。

我是不是做错了什么?

亲切的问候。

最佳答案

在您的示例中, sleep 意味着通常没有争用。无竞争锁非常快。为此,您需要一个竞争锁;如果在该争用中有写入,它们应该大致相同(lock 甚至可能更快) - 但如果它是大部分读取(很少有写入争用),我希望 ReaderWriterLockSlim 锁的性能优于 lock

就个人而言,我更喜欢这里的另一种策略,使用引用交换 - 因此读取始终可以读取而无需检查/锁定等。写入将它们更改为克隆副本,然后使用 Interlocked.CompareExchange 以交换引用(如果另一个线程在此期间更改了引用,则重新应用它们的更改)。

关于c# - ReaderWriterLockSlim 什么时候比简单的锁更好?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4217398/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com