Wielowątkowość w C# - Thread, Lock, SpinLock - Wersja do druku +- SafeGroup (https://safegroup.pl) +-- Dział: Forum ogólne (https://safegroup.pl/forum-6.html) +--- Dział: Programowanie - języki i technologie (https://safegroup.pl/forum-34.html) +---- Dział: C#, VB, VC++ .NET (https://safegroup.pl/forum-38.html) +---- Wątek: Wielowątkowość w C# - Thread, Lock, SpinLock (/thread-10238.html) |
Wielowątkowość w C# - Thread, Lock, SpinLock - chomikos - 09.04.2016 Często zdarza się, że mamy potrzebę wykonania kilku rzeczy w tym samym czasie. Przykładowo, pijąc herbatę możemy równocześnie oglądać telewizję czy czytać książkę. Podobnie w programowaniu – podczas (przykładowo) wykonywania jakiejś dłuższej pętli nie chcemy zawieszać programu (na czas jej wykonania), tylko wykonać w tym samym czasie inne operacje. W tym poście omówię pewną klasę i strukturę. Pierwsza z nich to Thread zawierający się w System.Threading; Pozwala on na wykonanie innej funkcji równolegle, nie naruszając/pauzując działania kodu. Przykładowo: Kod: using System; Daje wyjście: Jak widać dwa wątki (doLoop() oraz doLoop2()) wykonywane są w tym samym czasie, równolegle w stosunku do siebie. Synchronizacja Wyobraźmy sobie pewną sytuację. Próbujemy stworzyć pewien plik, nazwijmy go plik.txt i niech zostanie w przykładowym katalogu C:\Temp\. Najpierw musimy jednak sprawdzić, czy on istnieje. Przykładowo: Kod: static void Main(string[] args) Przejdziemy teraz do synchronizacji wątków za pomocą funkcji lock. Funkcja ta gwarantuje, że jeden wątek nie przejdzie do sekcji krytycznej kodu, podczas gdy inny jest w „swojej” sekcji krytycznej. Co więcej, w przypadku pracy z klasami, locki powinny być prywatne lub chronione. Dlaczego? Niektóre operacje muszą być wykonywane po kolei, nie mogą być równoległe. Spójrzmy na ten kawałek kodu: Kod: private object toSync = new object(); …i ten: Kod: private object toSync = new object(); są równoważne. Funkcja lock została stworzona jako referencja do klasy Monitor oraz niweluje potrzebę korzystania z bloku try. Teraz – do czego jest to potrzebne? Aby wątki nie przeszkadzały sobie wzajemnie. Wykonanie kodu w różnych wątkach operujących na tej samej zmiennej w pamięci może przynieść niepożądane skutki, takie jak „wykrzaczanie się” programu, co jest potencjalnym punktem zapalnym do exploitacji. Teraz przejdźmy do niskopoziomowej synchronizacji, która jest jednak rzadko używana (lock daje nam podobne możliwości bez zbędnych „bajerów”). Mówię tu o Spinlockach czyli w wolnym tłumaczeniu kręcących się blokadach. SpinLock można przedstawić mniej więcej tak: Kod: while(!isHandleFree); Wstrzymuje on działanie wątku tak długo, aż odpowiednia sekcja jest dostępna. Jest to zwyczajnie aktywna pętla sprawdzająca, czy wątek został zwolniony. SpinLocki używane są zazwyczaj tylko wtedy, gdy wydajność liczy się aż za bardzo. Są rodzajem pętli, która odpytuje, czy wątek jest zwolniony, i jeśli tak, wykonują kod. Jest to często szybsze, bo omija to serializację, nie ma potrzeby ingerowania w rejestry procesora. Trzeba mieć na uwadze to, że SpinLock nie jest klasą, lecz strukturą. Niżej podałem przykładowy kod z użyciem SpinLocka. Kod: using System; Przy tym, należy zaznaczyć, że Task jest asynchroniczny, a SpinLock właśnie go synchronizuje. I co ważne, przed wejściem w SpinLocka flaga lockTaken powinna być ustawiona na False. Wady SpinLocka? Wciąż aktywny, wykonuje cykle, „siedzi” na procesorze. W przypadku długich operacji lock jest duży lepszy od jego niskopoziomowego odpowiednika. RE: Wielowątkowość w C# - Thread, Lock, SpinLock - Tajny Współpracownik - 09.04.2016 (09.04.2016, 20:37)chomikos napisał(a):A co tutaj jest strukturą? RE: Wielowątkowość w C# - Thread, Lock, SpinLock - chomikos - 09.04.2016 (09.04.2016, 20:48)Tajny Współpracownik napisał(a):SpinLock jest strukturą w C#, nie klasą. RE: Wielowątkowość w C# - Thread, Lock, SpinLock - Tajny Współpracownik - 09.04.2016 A według mnie jest klasą. Aaaaa już kumam. Mnie tylko uczyli struktur w C RE: Wielowątkowość w C# - Thread, Lock, SpinLock - chomikos - 09.04.2016 (09.04.2016, 20:58)Tajny Współpracownik napisał(a): Luzik |