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

Widok: 46741|Odpowiedź: 7

[Źródło] Volatile vs. Interlocked vs. lock

[Skopiuj link]
Opublikowano 27.08.2018 14:40:35 | | |
Załóżmy, że istnieje klasa zawierająca publiczne pole licznika int, do którego może mieć dostęp wiele wątków, a ta liczba będzie tylko rosła lub malała.

Dodając to pole, które z poniższych schematów należy użyć i dlaczego?

  • lock(this.locker) this.counter++;
  • Interlocked.Increment (ref this.counter);
  • Zmień modyfikator dostępu z counter na public volatile


Najgorsze (żadne z nich tak naprawdę nie działa)

Zmień modyfikator dostępu z counter na public volatile

To podejście wcale nie jest bezpieczne, a istotą Volatile jest to, że wiele wątków działających na wielu procesorach buforuje dane i przestawia wykonywane instrukcje.

Jeśli jest nieulotny, gdy CPU A wzrasta o jakąś wartość, CPU B musi chwilę poczekać, aby zobaczyć wzrost wartości, co może prowadzić do problemów.

Jeśli jest to ulotność, zapewnia, że oba procesory widzą tę samą wartość w tym samym czasie. Ale nie unika to przekrojowych operacji odczytu i zapisu.

Dodanie wartości do zmiennej faktycznie wymaga trzech kroków

1. Czytanie, 2. Dodaj 3. Napisz

Załóżmy, że wątek A odczytuje wartość licznika jako 1 i nie jest gotowy do wzrostu, to wątek B również odczytuje wartość licznika jako 1, a oba wątki zaczynają wykonywać operacje przyrostowe i zapisujące. Wartość ostatniego licznika to 2. To nie jest poprawne, oba wątki wykonały operację wzrostu, a poprawny wynik powinien wynosić 3. Więc oznaczanie go jako niestabilnego jest po prostu niebezpieczne.

Lepiej

lock(this.locker) this.counter++;

W ten sposób jest bezpiecznie (pamiętaj, żeby zamknąć wszystkie miejsca, gdzie chcesz uzyskać dostęp do tego licznika, oczywiście). Zapobiega to wykonywaniu zablokowanego kodu przez inne wątki. Zapobiega też problemowi sekwencjonowania instrukcji wieloprocesorowego, o którym wspomniał wcześniej. Problem polega na tym, że blokada działa wolno, a jeśli używasz blokady w innych niepowiązanych miejscach, może to zablokować inne wątki.

Najlepsze

Interlocked.Increment (ref this.counter);

To bezpieczne i bardzo efektywne. Wykonuje trzy operacje odczytu, zwiększania, zapisu w jednym atomie bez przerwania w środku. Ponieważ nie wpływa to na inne kody, nie musisz pamiętać o zamkach gdzie indziej. Jest też bardzo szybki (jak mówi MSDN, na dzisiejszych procesorach często jest to tylko instrukcja).

Ale nie jestem do końca pewien, czy może to też rozwiązać problem kolejności instrukcji procesora, czy też trzeba go używać razem z Volatile i tym przyrostem.

Suplement: Jakie problemy lotne rozwiązują dobrze?

Ponieważ Volatile nie zapobiega wielowątkowości, co może zrobić? Dobrym przykładem są dwa wątki, jeden zawsze zapisuje do zmiennej, powiedzmy, że ta zmienna to queneLength, a drugi zawsze odczytuje dane z tej zmiennej. Jeśli QueueLongt nie jest ulotna, wątek A może odczytać 5 razy, ale wątek B może zobaczyć opóźnione dane lub nawet dane w niewłaściwej kolejności. Jednym z rozwiązań jest użycie blokady, ale w tym przypadku można też użyć lotności. Zapewnia to, że wątek B zawsze widzi najnowsze dane zapisane przez wątek A, ale ta logika działa tylko wtedy, gdy nie czytasz ich podczas zapisu i jeśli nie zapisujesz ich podczas odczytu. Gdy wiele wątków chce wykonać operacje czytania-modyfikowania-zapisu, trzeba użyć Interlocked lub Lock.





Poprzedni:Metoda szyfrowania Java MD5
Następny:Linq implementuje nie w i w zapytaniach warunkowych w SQL
Opublikowano 29.08.2018 16:21:42 |
Cześć, kod, który zrobiłeś wcześniej, łączący highcharty z ułożonymi histogramami i drillowalnymi histogramami? Chciałbym zapytać, czy możesz przesłać kod, który można edytować na interfejsie https://jshare.com.cn/demos/hhhhDz?hc-theme=grid-light?
Opublikowano 29.08.2018 16:22:13 |
Cała sieć to po prostu twój zasób.
Opublikowano 29.08.2018 16:22:55 |
Bo poprzednie 90 lat temu nie potrafiło zostawić żadnej wiadomości. więc
Opublikowano 29.08.2018 16:40:40 |
Czy wygodnie jest dodać dane kontaktowe? Skonsultuj się z tobą
 Ziemianin| Opublikowano 15.09.2018 13:10:16 |
prywatny statyczny int safeInstanceCount = 0; Współpraca z atomami
System.Threading.Interlocked.Increment(ref safeInstanceCount); Samo-wzrost 1
System.Threading.Interlocked.Decrement(ref safeInstanceCount); Własność minus 1
Opublikowano 21.05.2020 16:43:54 |
Wspieraj właściciela w udostępnianiu
 Ziemianin| Opublikowano 11.06.2020 15:00:16 |
1. Koncepcja

W środowisku wielowątkowym operacje nieprzerwane przez mechanizmy planowania wątków; Po rozpoczęciu operacji trwa do końca, bez przełączania kontekstu (przełączania się na inny wątek) pomiędzy nimi.

2. Klasa

System.Threading.Interlocked klasa statyczna

3. Funkcje powszechnie używane (patrz pozostałe)

1. publiczna statyczna int Decrement (referencja int location); Decruj wartość określonej zmiennej w postaci operacji atomowej i zapisz wynik

Równoważne do lock(obj){i--; }

2. publiczna statyczność inkrementu (odniesienie do lokalizacji); Zwiększ wartość określonej zmiennej w formie operacji atomowej i przechowuj wynik

Równoważny do lock(obj){i++; }
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