Przesuwamy się ku coraz trudniejszym tematom i tym razem rozpocznę temat wątków. Wątek w programowaniu jest już zaawansowanym rozdziałem i nawet doczekał się własnego działu naukowego, "programowanie współbieżne". Bez względu na wszystko, trzeba zacząć od samego początku i najpierw wyjaśnić sobie teorię zanim przejdziemy do części praktycznej. Zapraszam serdecznie do wpisu.
Tweet |
WĄTEK W PROGRAMOWANIU TO TRUDNY WĄTEK DO OPANOWANIA
Żadne odkrycie, aczkolwiek wszystko co na tym świecie jest trudne, nie jest awykonalne. Rozpocznijmy od definicji: wątek to osobny, niezależny stos wywołań wykonujący się równolegle razem z "głównym" stosem (zapoczątkowanym przez punkt startowy jakim jest najczęściej funkcja "main"). Pozwala on na wykonywanie innego przydzielonego zadania, który w założeniach programisty musi przebiegać niezależnie od jedynego "ciągu" wykonywanych poleceń. Pamiętacie zapewne jak działa stos wywołań metod. To wyobraźcie sobie teraz, że tworząc nowy wątek w programowaniu, powstaje drugi taki stos położony tuż obok pierwszego i oba idą własnym tokiem nie przeszkadzając sobie nawzajem, choć mogą od siebie wymagać pewnych wyników, o czym piszę poniżej.
ZNANE PROBLEMY PRZY KORZYSTANIU Z WĄTKÓW
Temat ten robi się o wiele bardziej skomplikowany gdy używa się go w praktyce. Jednym ze znanych problemów jest spójność danych. Chodzi o sytuację, w której dwa osobne wątki operują na tej samej danej. Mimo tego, że wątek w programowaniu to osobny stos wywołań, to jednak pożądanym zawsze jest operowanie na tych samych zmiennych oraz żeby ich modyfikacje były trwałe i miały wpływ na dalszy ciąg postępowania innego wątku. Być może niektórzy z Was kojarzą słowo kluczowe w języku C, "volatile". Stanowi to powszechnie stosowaną ochronę przed przyjmowaniem indywidualnych wartości przez każdy wątek. W praktyce, gdy jakaś zmienna była dla przykładu równa 7 i przyjmowała taką samą wartość dla wielu wątków, to gdy w jednym z nich wykonywana była dowolna modyfikacja (np. inkrementacja), to ta zmiana była trwała i dotyczyła całej reszty wątków. W przeciwnym razie, po zakończeniu wątku który modyfikował tę liczbę, zmienna dalej byłaby "siódemką" i nie byłoby śladu po tej modyfikacji. Traktujcie ten przypadek jako abstrakcyjne uproszczenie tego dylematu, w nadziei że wiecie o co chodzi.
Zmienna "ulotna" ("volatile") wykorzystywana jest podczas współbieżności w celu utrwalenia modyfikacji danych jednego z wątków, aby ta sama wartość obowiązywała dla całej reszty zadań.
Drugi znany problem to ryzyko zakleszczenia się wątków (ang. "deadlock"). Wątek w programowaniu też może tego doświadczyć. Wykonują się co najmniej dwa zadania równolegle i dochodzi do momentu, w którym działanie jednego wątku jest zależne od drugiego i na odwrót. Jeden wątek wykonuje jakieś zadanie. W momencie gdy zaczął go wykonywać, został na chwilę "wstrzymany" (ale dalej "siedzi" w środku tego zadania). Drugi wątek teraz ma prawo działać i wykonuje jakieś inne zadanie, ale jest ono powiązane z zadaniem wątku pierwszego. Obecnie działający wątek jest usypiany, czeka na pomyślne wykonanie zadania wątku pierwszego. Wtedy do akcji powraca wątek pierwszy, który nie skończył swojego zadania i już go nie skończy, ponieważ podstawą do zakończenia swojego działania jest wywołanie jednej z metod dotyczących zadania przeprowadzanego przez wątek sąsiedni. Dochodzi do "zakleszczenia się" wzajemnie obu wątków, gdyż zadanie "sąsiada" ma wpływ na kontynuację swojego zadania. Nic przyjemnego, prawda?
Wzajemna blokada wątków pojawia się w sytuacji, gdy dwa lub więcej wątków nie może zakończyć swojego zadania z powodu powstałej zależności od innego wątku, który on sam również wymaga zakończenia zadań u "sąsiada".
Wątek w programowaniu posiada nieco szersze wsparcie i choć to samo słowo kluczowe "volatile" również występuje do tych samych celów, to można też skorzystać z mechanizmu synchronizacji jakie wspierają niektóre języki wysokiego poziomu np. Java. Ten artykuł dokładnie opisuje proces metod synchronizowanych razem z przykładowym kodem źródłowym.
Na sam wstęp do programowania współbieżnego widziałbym tyle podstawowych informacji. Jeśli rozumiecie teorię dosyć dobrze, to dopiero wtedy możecie zabrać się za kodowanie.