Ten artykuł jest lustrzanym artykułem tłumaczenia maszynowego, kliknij tutaj, aby przejść do oryginalnego artykułu.

Widok: 18751|Odpowiedź: 0

[Napiwki] C# Read/Write Lock ReaderWriterLockSlim

[Skopiuj link]
Opublikowano 09.03.2017 16:59:19 | | | |
Koncepcja blokad odczytu-zapisu jest prosta – pozwala wielu wątkom jednocześnie uzyskać blokady odczytu, ale tylko jeden wątek może jednocześnie uzyskać blokady zapisu, dlatego nazywa się je również zamkami wyłącznymi współdzielonymi. W C# zaleca się użycie klasy ReaderWriterLockSlim do ukończenia funkcji blokady odczytu/zapisu.
W niektórych przypadkach liczba odczytów obiektu jest znacznie większa niż liczba modyfikacji, a jeśli obiekt jest po prostu zablokowany przez blokadę, wpływa to na efektywność odczytu. Jeśli użyty jest blok odczyt-zapis, wiele wątków może jednocześnie odczytywać obiekt i będzie on blokowany tylko wtedy, gdy obiekt jest zajęty przez blokadę zapisu.
Mówiąc prosto, gdy wątek wchodzi w tryb czytania, inne wątki nadal mogą wejść w tryb odczytu, zakładając, że wątek chce wejść w tryb zapisu w tym momencie, to musi zostać zablokowany. Aż do wyjścia trybu odczytu.
Podobnie, jeśli wątek przejdzie w tryb zapisu, pozostałe wątki zostaną zablokowane, niezależnie od tego, czy chcą pisać, czy czytać.
Istnieją dwa sposoby na wejście w tryb zapisu/odczytu:
EnterReadLock próbuje wejść w stan blokady w trybie zapisu.
TryEnterReadLock(Int32) próbuje wejść w stan blokady w trybie odczytu, z opcją wyboru limitu czasu całkowitoliczbowego.
EnterWriteLock próbuje wejść w stan Write Mode Lock.
TryEnterWriteLock(Int32) próbuje wejść w stan blokady trybu zapisu, a czas przekroczenia czasu można wybrać.
Istnieją dwa sposoby wyjścia z trybu zapisu/odczytu:
ExitReadLock zmniejsza liczbę rekurencji trybu odczytu i wychodzi z trybu odczytu, gdy liczba wynosi 0 (zero).
ExitWriteLock zmniejsza rekurencyjną liczbę wzorców zapisu i kończy tryb zapisu, gdy uzyskana liczba wynosi 0 (zero).
Oto jak go używać:



Widać, że wątek 3 i 4 mogą wchodzić w tryb odczytu jednocześnie, natomiast wątek 5 może przejść w tryb zapisu po 5 sekundach (czyli po opuszczeniu blokady odczytu przez wątki 3 i 4).
Zmodyfikuj powyższy kod, najpierw otwórz 2 wątki w trybie zapisu, a następnie otwórz wątki w trybie odczytu, a kod wygląda następująco:
      


Wyniki są następujące:

Jak widać, wątek 3 i 4 wchodzą w tryb zapisu, ale wątek 3 zajmuje blokadę zapisu jako pierwszej, więc wątek 4 musi czekać 10 sekund przed wejściem. Wątki 5 i 6 muszą zajmować blokadę odczytu, więc poczekajcie, aż wątek 4 opuści blokadę zapisu, zanim kontynuowamy.
TryEnterReadLock i TryEnterWriteLock mogą ustawić timeout, uruchamiając to zdanie, wątek zablokuje tutaj, jeśli blokada może być zajęta w tym czasie, wtedy zwróć true, jeśli timeout jeszcze nie zajął blokady, wtedy zwróć false, rezygnuj z zajęcia blokady i kontynuuj wykonywanie następującego kodu bezpośrednio.
EnterUpgradeableReadLock
Klasa ReaderWriterLockSlim zapewnia tryb odczytu z możliwością ulepszenia, który różni się od trybu odczytu tym, że można ją również zaktualizować do trybu zapisu, wywołując metody EnterWriteLock lub TryEnterWriteLock. Ponieważ tylko jeden wątek może być w trybie ulepszania w danym momencie. Wątek, który wchodzi w tryb ulepszania, nie wpłynie na wątek w trybie odczytu, czyli gdy wątek przejdzie w tryb ulepszania, dowolna liczba wątków może jednocześnie przejść w tryb odczytu bez blokowania. Jeśli wiele wątków już czeka na uzyskanie blokady zapisu, uruchomienie EnterUpgradeableReadLock zablokuje do momentu wygaśnięcia czasu lub wyjścia z blokady zapisu.
Poniższy kod pokazuje, jak zaktualizować system do blokady zapisu w trybie rozbudowywalnego odczytu.



Wpływ blokad odczytu/zapisu na wydajność jest oczywisty.
Następujący kod testowy:


Powyższy kod symuluje działanie 500 zadań, z których każde zajmuje wątek puli wątków, z czego 20 to wątki zapisu, a symulowane 480 wątków odczytu. Odczyt danych zajmuje 10 ms, a zapis 100 ms, aby przetestować odpowiednio metodę blokady i metodę ReaderWriterLockSlim. Można oszacować, że dla ReaderWriterLockSlim można oszacować, zakładając, że 480 wątków czytanych jednocześnie, to zużywa 10ms, 20 operacji zapisu zajmuje 2000ms, więc czas zużywany wynosi 2010ms, a dla zwykłej metody blokady, ponieważ wszystkie są wyłączne, więc 480 operacji odczytu zajmuje 4800ms + 20 operacji zapisu, 2000ms = 6800ms. Wyniki wykazały zauważalną poprawę wydajności.






Poprzedni:Visual Studio 2017 pakiet instalacyjny offline, 18GB Baidu do pobrania w chmurze
Następny:Najnowsze luki i metody ataku w wersjach Struts2 2.2 i 2.3
Zrzeczenie się:
Całe oprogramowanie, materiały programistyczne lub artykuły publikowane przez Code Farmer Network służą wyłącznie celom edukacyjnym i badawczym; Powyższe treści nie mogą być wykorzystywane do celów komercyjnych ani nielegalnych, w przeciwnym razie użytkownicy ponoszą wszelkie konsekwencje. Informacje na tej stronie pochodzą z Internetu, a spory dotyczące praw autorskich nie mają z nią nic wspólnego. Musisz całkowicie usunąć powyższą zawartość z komputera w ciągu 24 godzin od pobrania. Jeśli spodoba Ci się program, wspieraj oryginalne oprogramowanie, kup rejestrację i korzystaj z lepszych, autentycznych usług. W przypadku naruszenia praw prosimy o kontakt mailowy.

Mail To:help@itsvse.com