ReaderWriterLockSlim в C#
Класс ReaderWriterLockSlim разрешает нескольким потокам читать одновременно, но писать может только один. Пока идёт запись, новые читатели ждут. Так ускоряют чтение редко меняющихся данных.
Замок чтения снимают в finally, иначе следующий поток будет ждать его вечно. В примере запись не входит в секцию, а только проверяет, свободна ли она.
Два потока входят в чтение, а запись в этот момент пытается начаться и не ждёт. Сигнал поднимается, когда первый читатель уже внутри, короткая пауза даёт второму успеть войти. Попытка записи сразу не удалась:
using ReaderWriterLockSlim rw = new();
int readersInside = 0;
int writerWaited = 0;
ManualResetEvent readersReady = new(false);
void ReadWork()
{
rw.EnterReadLock();
try
{
Interlocked.Increment(ref readersInside);
readersReady.Set();
Thread.Sleep(30);
}
finally { rw.ExitReadLock(); }
}
Thread r1 = new(ReadWork);
Thread r2 = new(ReadWork);
r1.Start();
r2.Start();
readersReady.WaitOne();
Thread.Sleep(10);
if (!rw.TryEnterWriteLock(0))
writerWaited = 1;
r1.Join();
r2.Join();
Console.WriteLine(writerWaited); // выведет 1
Запустите два потока, которые одновременно читают общее поле. Пока чтение ещё идёт, попробуйте начать запись без ожидания. Выведите строку "busy", если запись не началась сразу.