Według MSDN program ReaderWriterLockSlim faworyzuje pisarzy. Oznacza to, że jeśli w kolejce znajdują się czytniki i piszący, pisarze będą mieli pierwszeństwo.
Może to spowodować głód czytelnika, kod testowy do odtworzenia to here. Zakładam, że głodzenie może się zdarzyć tylko wtedy, gdy pisanie jest długotrwałe, z włączonym przełącznikiem kontekstu wątku. Przynajmniej jest zawsze reprodukowane na moim komputerze, więc proszę powiedz mi, czy się mylę.
Z drugiej strony, ReaderWriterLock z .net 2.0 nie wytwarza ani głodu czytelników, ani pisarzy, kosztem obniżonej wydajności. Here to zmodyfikowany kod z poprzedniej próbki, aby pokazać, że nie ma żadnego głodu.
Powracając do pytania - zależy to od tego, jakie funkcje wymagają blokady RW. Blokady rekursywne, obsługa wyjątków, limity czasu - najbardziej zbliżone do jakości produkcji Blokada RW, która obsługuje wszystkie powyższe, i preferuje czytelników prawdopodobnie będzie ReaderWriterLock.
Możesz również przyjąć kod z artykułu wiki opisującego first readers-writers problem, ale oczywiście musisz zaimplementować wszystkie wymagane funkcje z góry ręcznie, a wdrożenie będzie miało problem z pisarzem-głodem.
Blokada rdzeń może prawdopodobnie wyglądać następująco:
class AutoDispose : IDisposable
{
Action _action;
public AutoDispose(Action action)
{
_action = action;
}
public void Dispose()
{
_action();
}
}
class Lock
{
SemaphoreSlim wrt = new SemaphoreSlim(1);
int readcount=0;
public IDisposable WriteLock()
{
wrt.Wait();
return new AutoDispose(() => wrt.Release());
}
public IDisposable ReadLock()
{
if (Interlocked.Increment(ref readcount) == 1)
wrt.Wait();
return new AutoDispose(() =>
{
if (Interlocked.Decrement(ref readcount) == 0)
wrt.Release();
});
}
}
Porównywanie wydajności 3 implementacjach, stosując 3 czytelnika i 3 wątki pisarz, za pomocą prostych w pamięci operacji (za pomocą operacji długo blokuje przyniosłoby czytelnika głód na RWLockSlim i pisarz-głód na zlecenie zamka):
i upewnić się, że pętla obciążenie nie jest rozwijana przez kompilator, ale mogą istnieć inne pułapek nie jestem świadomy, więc t wykonaj te pomiary z przymrużeniem oka. Kod źródłowy do testów to here.
Brak kodu nigdy nie może zostać udowodniony jednoznacznie. Ale nie, to mało prawdopodobne. Unikaj pytań o zakupy. –
Jeśli chcesz faworyzować odczyty, dlaczego po prostu nie zastąpisz wewnętrznej listy zaktualizowanym klonem? Twój kod zostanie zablokowany, ale nieco cięższy od aktualizacji. – jgauffin
Tak, brzmi to tak, jakbyś mógł rozwiązać to albo z kopią, jak sugeruje jgauffin, albo jeśli struktura danych jest zbyt duża dla taniej kopii, z buforem zapisu, więc zapisy są rzadsze. Następnie można po prostu dostosować saldo odczytu/zapisu, zwiększając lub zmniejszając czas, aby opróżnić bufor. –