Co to jest rywalizacja wątków?


121

Czy ktoś może po prostu wyjaśnić, czym jest spór o wątek?

Przeszukałem go w Google, ale nie mogę znaleźć prostego wyjaśnienia.


10
Wypisz więc, jakie są Twoje niejasne myśli, abyśmy mogli zobaczyć, gdzie możesz być wyłączony lub Twoje zrozumienie może być poprawne.
James Black

Odpowiedzi:


88

Zasadniczo rywalizacja wątków jest stanem, w którym jeden wątek oczekuje na blokadę / obiekt, który jest obecnie utrzymywany przez inny wątek. Dlatego ten wątek oczekujący nie może używać tego obiektu, dopóki inny wątek nie odblokuje tego konkretnego obiektu.


53
Ta odpowiedź jest niekompletna (jak większość innych). Chociaż zamek jest jednym z rodzajów rzeczy, o które można spierać się, nie jest jedyną taką rzeczą. Może również istnieć rywalizacja o zasoby bez zamków. (Na przykład, jeśli dwa wątki nadal niepodzielnie zwiększają tę samą liczbę całkowitą, mogą napotkać rywalizację z powodu pingowania pamięci podręcznej. Brak blokad).
David Schwartz

W przypadku globalnej blokady interpretera (GIL), takiej jak w CPython, gdzie wątek musi zawsze uzyskać GIL, wiele wątków działających w tym samym procesie jest więc domyślnie rywalizowanych.
Acumenus,

Myślę, że wyjaśniłeś to w kategoriach impasu, ale bardzo różni się on od impasu.
Harshit Gupta

185

Wydaje się, że kilka odpowiedzi koncentruje się na rywalizacji o blokady, ale blokady nie są jedynymi zasobami, w przypadku których można doświadczyć rywalizacji. Rywalizacja polega po prostu na tym, że dwa wątki próbują uzyskać dostęp do tego samego zasobu lub powiązanych zasobów w taki sposób, że co najmniej jeden z rywalizujących wątków działa wolniej, niż gdyby nie działały inne wątki.

Najbardziej oczywistym przykładem niezgody jest zamek. Jeśli wątek A ma blokadę i wątek B chce uzyskać tę samą blokadę, wątek B będzie musiał poczekać, aż wątek A zwolni blokadę.

Teraz jest to specyficzne dla platformy, ale wątek może ulec spowolnieniu, nawet jeśli nigdy nie będzie musiał czekać, aż inny wątek zwolni blokadę! Dzieje się tak, ponieważ blokada chroni pewne rodzaje danych, a same dane często również są przedmiotem rywalizacji.

Na przykład rozważmy wątek, który uzyskuje blokadę, modyfikuje obiekt, a następnie zwalnia blokadę i robi inne rzeczy. Jeśli robią to dwa wątki, nawet jeśli nigdy nie walczą o blokadę, mogą one działać znacznie wolniej niż gdyby działał tylko jeden wątek.

Czemu? Powiedzmy, że każdy wątek działa na własnym rdzeniu na nowoczesnym procesorze x86, a rdzenie nie współużytkują pamięci podręcznej L2. Mając tylko jeden wątek, obiekt może pozostawać w pamięci podręcznej L2 przez większość czasu. Gdy oba wątki są uruchomione, za każdym razem, gdy jeden wątek modyfikuje obiekt, drugi wątek stwierdzi, że dane nie znajdują się w jego pamięci podręcznej L2, ponieważ inny procesor unieważnił linię pamięci podręcznej. Na przykład na Pentium D spowoduje to działanie kodu z szybkością FSB, która jest znacznie mniejsza niż szybkość pamięci podręcznej L2.

Ponieważ rywalizacja może wystąpić nawet wtedy, gdy sama blokada nie jest przedmiotem rywalizacji, rywalizacja może również wystąpić, gdy nie ma blokady. Na przykład załóżmy, że Twój procesor obsługuje atomową inkrementację zmiennej 32-bitowej. Jeśli jeden wątek ciągle zwiększa i zmniejsza wartość zmiennej, zmienna będzie przez większość czasu gorąca w pamięci podręcznej. Jeśli zrobią to dwa wątki, ich pamięci podręczne będą walczyć o własność pamięci przechowującej tę zmienną, a wiele dostępów będzie wolniejszych, ponieważ protokół spójności pamięci podręcznej działa w celu zabezpieczenia własności każdego rdzenia linii pamięci podręcznej.

Jak na ironię, zamki zazwyczaj zmniejszają rywalizację. Czemu? Ponieważ bez blokady dwa wątki mogłyby działać na tym samym obiekcie lub kolekcji i powodować wiele rywalizacji (na przykład istnieją kolejki bez blokad). Blokady będą miały tendencję do usuwania harmonogramu wątków rywalizujących, umożliwiając zamiast tego uruchamianie wątków nie rywalizujących. Jeśli wątek A przechowuje blokadę, a wątek B chce tej samej blokady, implementacja może zamiast tego uruchomić wątek C. Jeśli wątek C nie potrzebuje tej blokady, można przez chwilę uniknąć przyszłej rywalizacji między wątkami A i B. (Oczywiście przy założeniu, że istnieją inne wątki, które mogą działać. Nie pomoże, jeśli jedynym sposobem, w jaki system jako całość może zrobić użyteczny postęp, będzie uruchamianie wątków, które rywalizują).


4
+1 Ponadto, żeby to wyraźnie zaznaczyć, dwie zmienne, o które walczą dwa rdzenie, nie muszą nawet być tą samą zmienną, aby wywołać rywalizację, muszą być tylko przechowywane w pamięci w tej samej linii pamięci podręcznej. Struktury wypełniające i / lub dopasowywanie struktur do pamięci może pomóc uniknąć tej formy rywalizacji.
Rob_before_edits,

1
@David, pomóż bardziej szczegółowo zrozumieć ostatni akapit twojej odpowiedzi
Learner

4
@Naroji Zadaj pytanie na ten temat.
David Schwartz

@DavidSchwartz, Czy jesteś programistą C?
Pacerier

@Pacerier C ++ głównie.
David Schwartz,

19

Od tutaj :

Rywalizacja występuje, gdy wątek oczekuje na zasób, który nie jest łatwo dostępny; spowalnia wykonywanie kodu, ale może z czasem ulec wyjaśnieniu.

Zakleszczenie występuje, gdy wątek oczekuje na zasób, który został zablokowany przez drugi wątek, a drugi wątek oczekuje na zasób, który został zablokowany przez pierwszy wątek. Zakleszczenie może obejmować więcej niż dwa wątki. Impas nigdy nie ustępuje sam. Często powoduje zatrzymanie całej aplikacji lub części, w której występuje impas.


To również wyjaśnia różnicę między wątkiem Contention a Deadlock
Sankalp

3

Myślę, że w kontekście tego pytania powinno być jakieś wyjaśnienie z PO - przychodzą mi do głowy 2 odpowiedzi (chociaż jestem pewien, że są dodatki do tej listy):

  1. jeśli odnosisz się do ogólnej „koncepcji” rywalizacji o wątki i tego, jak może ona prezentować się w aplikacji, odwołam się do szczegółowej odpowiedzi @ DavidSchwartz powyżej.

  2. Istnieje również licznik wydajności „.NET CLR Locks and Threads: Total # of Contentions”. Jak zaczerpnięto z opisu PerfMon dla tego licznika, jest on zdefiniowany jako:

    Ten licznik wyświetla całkowitą liczbę razy, kiedy wątki w środowisku CLR próbowały uzyskać zarządzaną blokadę bez powodzenia. Zarządzane zamki można zdobyć na wiele sposobów; przez instrukcję „lock” w C # lub wywołując System.Monitor.Enter lub używając atrybutu niestandardowego MethodImplOptions.Synchronized.

... i jestem pewien, że inne dla innych systemów operacyjnych i frameworków aplikacji.


2

Masz 2 wątki. Wątek A i Wątek B, masz również obiekt C.

Obecnie A uzyskuje dostęp do obiektu C i nałożył blokadę na ten obiekt. B musi uzyskać dostęp do obiektu C, ale nie może tego zrobić, dopóki A nie zwolni blokady obiektu C.


1

Innym słowem może być współbieżność. Jest to po prostu idea dwóch lub więcej wątków próbujących użyć tego samego zasobu.


1

Dla mnie rywalizacja to rywalizacja między 2 lub więcej wątkami o wspólny zasób. Zasobem może być zamek, licznik itp. Konkurencja oznacza „kto pierwszy ją otrzyma”. Im więcej wątków, tym większa rywalizacja. Im częstszy dostęp do zasobu, tym większa rywalizacja.


1

Wyobraź sobie następujący scenariusz. Przygotowujesz się do jutrzejszego egzaminu końcowego i czujesz się trochę głodny. Więc daj swojemu młodszemu bratu dziesięć dolców i poproś go, żeby kupił ci pizzę. W tym przypadku jesteś głównym wątkiem, a twój brat jest wątkiem podrzędnym. Po otrzymaniu zamówienia zarówno ty, jak i twój brat wykonujesz swoją pracę jednocześnie (np. Uczą się i kupują pizzę). Teraz mamy do rozważenia dwa przypadki. Po pierwsze, twój brat przynosi twoją pizzę i kończy naukę. W takim przypadku możesz przestać się uczyć i cieszyć się pizzą. Po drugie, kończysz naukę wcześnie i śpisz (tj. Twoja przydzielona praca na dziś - nauka do jutrzejszego egzaminu końcowego - jest wykonana), zanim pizza będzie dostępna. Oczywiście nie możesz spać; w przeciwnym razie nie będziesz miał okazji zjeść pizzy.

Tak jak w przykładzie, oba przypadki nadają sens rywalizacji.


0

Na rywalizację wątków wpływają również operacje we / wy. Przykład, gdy wątek oczekujący na odczyt pliku może zostać uznany za rywalizację. Użyj portów zakończenia we / wy jako rozwiązania.


0

Rywalizacja o blokadę ma miejsce, gdy wątek próbuje uzyskać blokadę do obiektu, który został już przejęty przez inny wątek *. Do momentu zwolnienia obiektu wątek jest blokowany (innymi słowy jest w stanie Oczekiwanie). W niektórych przypadkach może to prowadzić do tak zwanego wykonywania seryjnego, co negatywnie wpływa na aplikację.

z dokumentacji dotTrace

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.