Wykład 10 - boost Thread. 8 czerwca 2007
Równoległość bardzo wolna reakcja człowieka wolne urządzenia wejścia - wyjścia (np. drukarki) bardzo szybkie procesory można przeprowadzać obliczenia podczas obsługi urządzeń Pojęcie równoległości: na platformach jednoprocesorowych (jednordzeniowych) na platformach wieloprocesorowych (wielordzeniowych) wieloprocesowe systemy operacyjne
Aplikacje wielowątkowe Wątek ( lekki proces ), pozwala realizować niezależne ciągi instrukcji w ramach procesu. Wątki współdzielą kod i dane (przestrzeń adresową) oraz zasoby. lepiej wykorzystuje dostępną moc obliczeniową pozwalają na obsługę wielu zleceń równolegle mechanizm nie wprowadza dużych narzutów. Stany wątku gotowy wykonywany zatrzymany blokowany
wątki (2) Współdzielone są: zmienne statyczne i globalne sterta (heap) i zmienne dynamiczne (adres jest unikalny niezależnie od wątku) obiekty automatyczne (na stosie) jeżeli dostęp jest przez wskaźnik lub referencje zasoby systemu operacyjnego (pliki, okna itp) kod wykonywany Niezależne są: rejestry, ciąg wykonywanych instrukcji, stos zmienne automatyczne Program ma zawsze jeden wątek (funkcja main() ) - wątek główny lub inicjujący. Może tworzyć dodatkowe wątki.
Wątki a C++ C++ jest przygotowany do implementacji aplikacji wielowątkowych większość funkcji z biblioteki standardowej może być bezpiecznie używana w różnych wątkach należy używać bibliotek przeznaczonych do pracy wielowątkowej (np. obsługa sterty) zabronione funkcje (przechowują stan pomiędzy wołaniami) rand (<cstdlib>) strtok (<cstring>) asctime, ctime, gmtime, localtime (<ctime>) standard języka nie dostarcza mechanizmów tworzenia i synchronizacji wątków
boost::thread - wątki w C++ #include <boost/thread/thread.hpp> //Funkcja główna wątku użytkownika void my_thread() { /*... */ } //Można też użyć funktora class MyThread { public: //tutaj implementacja funkcji wątku użytkownika void operator()() { /*... */ } }; int main() { boost::thread thrd(&my_thread); //Utworzenie i uruchomienie wątku thrd.join(); //Biezacy watek czeka na zakonczenie watku thrd }
Problemy z programowaniem równoległym wyścigi (race conditions): wiele wątków pisze lub czyta tę samą pamięć niewłaściwa wartość ( niezdefiniowane zachowanie ). watek 1 watek 2 nr:12 wolne znajduje wolne miejsce znajduje wolne miejsce nr:12 zajęte klient1 rezerwuje miejsce rezerwuje miejsce czas nr:12 zajęte klient2 rozwiązanie problemu: synchronizacja (blokady)
Blokady w boost mutex (mutual-execution) jest używany do szeregowania dostępu do zasobu. Stany: zablokowany, odblokowany. //Utworzenie obiektu służącego do synchronizacji boost::mutex mutex_resource; /*... */ { //scoped_lock - zdobywanie jest inicjacją, //konstruktor: lock, destruktor: unlock boost::mutex::scoped_lock scoped_lock(mutex_resource); //Tutaj dostęp do zasobu }//Tutaj zwolnienie zasobu boost::mutex boost::try_mutex boost::timed_mutex boost::read_write_mutex boost::try_read_write_mutex boost::timed_read_write_mutex boost::recursive_mutex boost::recursive_try_mutex boost::recursive_timed_mutex
Problemy przy stosowaniu blokad zakleszczenia (deadlock) zagłodzenia (starvation) Watek 1 Watek 2 blokuj A blokuj B blokuj B czeka na zwolnienie B blokuj A czas czeka na zwolnienie A
problemy z usuwaniem błędów w aplikacjach wielowątkowych niektóre błędy są niepowtarzalne różne zachowanie się wersji debug od release debugger potrzebuje specjalnego wsparcia aby pokazać stany wątków testy na platformach z jednym procesorem (rdzieniem) mogą nie pokazywać błędów które wystąpią na platformach posiadających wiele procesorów (rdzieni) trudno testować wszystkie możliwe przebiegi sterowania
Typowe kończenie wątku nie ma możliwości przerwania wątku z zewnątrz class MyThread { public: MyThread() : finish_(false) {} void finish() { finish_ = true; } void operator()() { while(!finish_) { /* tutaj część przetwarzania */ /* a następnie sprawdzanie warunku!finish_ */ } } private: volatile bool finish_; };
Podsumowanie aplikacje wielowątkowe są coraz bardziej powszechne boost zapewnia obiekty reprezentujące wątki oraz mechanizmy synchronizacyjne wątki i mechanizm wyjątków