Problemy współbieżności

Podobne dokumenty
Przetwarzanie wielowątkowe przetwarzanie współbieżne. Krzysztof Banaś Obliczenia równoległe 1

Programowanie równoległe i rozproszone. W1. Wielowątkowość. Krzysztof Banaś Programowanie równoległe i rozproszone 1

Programowanie równoległe i rozproszone. Monitory i zmienne warunku. Krzysztof Banaś Programowanie równoległe i rozproszone 1

Tworzenie programów równoległych. Krzysztof Banaś Obliczenia równoległe 1

Tworzenie programów równoległych cd. Krzysztof Banaś Obliczenia równoległe 1

w odróżnieniu od procesów współdzielą przestrzeń adresową mogą komunikować się za pomocą zmiennych globalnych

synchronizacji procesów

synchronizacji procesów

Tworzenie programów równoległych. Krzysztof Banaś Obliczenia równoległe 1

Mariusz Rudnicki PROGRAMOWANIE SYSTEMÓW CZASU RZECZYWISTEGO CZ.4

Wielowątkowy serwer TCP

Tworzenie programów równoległych. Krzysztof Banaś Obliczenia równoległe 1

Programowanie współbieżne Wykład 10 Synchronizacja dostępu do współdzielonych zasobów. Iwona Kochańska

Temat zajęć: Tworzenie i obsługa wątków.

Mariusz Rudnicki PROGRAMOWANIE WSPÓŁBIEŻNE I SYSTEMY CZASU RZECZYWISTEGO CZ.4

1. Uruchom poniższy program tworzący pojedynczy wątek:

J. Ułasiewicz Programowanie aplikacji współbieżnych 1

Wykład 4. Synchronizacja procesów (i wątków) cześć I. Wojciech Kwedlo, Wykład z Systemów Operacyjnych -1- Wydział Informatyki PB

SOP2 - semafory. grudzień

Gdy kilka procesów czyta a przynajmniej jeden dokonuje zapisu wynik odczytu zależeć może od sposobu realizacji przeplotu.

Synchronizacja procesów i wątków

Programowanie Równoległe i Rozproszone

Synchronizacja procesów

J. Ułasiewicz Programowanie aplikacji współbieżnych 1

Modele programowania równoległego. Pamięć współdzielona Rafał Walkowiak dla III roku Informatyki PP

Monitory. Jarosław Kuchta

Proces z sekcją krytyczną. Synchronizacja procesów. Synchronizacja procesów, cd. Synchronizacja procesów, cd. Synchronizacja procesów, cd

Plan wykładu. Obliczenia równoległe w zagadnieniach inżynierskich. Wykład 1 p. Wzajemne wykluczanie. Procesy współbieżne

Systemy operacyjne. Zajęcia 11. Monitory

Wykład 4. Synchronizacja procesów (i wątków) cześć I. Wojciech Kwedlo, Wykład z Systemów Operacyjnych -1- Wydział Informatyki PB

Architektury systemów równoległych

Problemy czytelników i pisarzy oraz 5 ucztujących filozofów

Procesy i wątki. Krzysztof Banaś Obliczenia równoległe 1

Programowanie współbieżne Wykład 4. Rafał Skinderowicz

Klasyczne problemy synchronizacji

Wykład 5. Synchronizacja (część II) Wojciech Kwedlo, Wykład z Systemów Operacyjnych -1- Wydział Informatyki PB

Semafor nie jest mechanizmem strukturalnym. Aplikacje pisane z użyciem semaforów są podatne na błędy. Np. brak operacji sem_post blokuje aplikację.

Semafory. // G - globalna dla wszystkich. // Wada - aktywne oczekiwanie Test_and_Set(Li); exit when Li = 0; end loop sekcja_krytyczna(i); G := 0;

Plan wykładu. Programowanie aplikacji równoległych i rozproszonych. Wykład 1 p. Wzajemne wykluczanie. Procesy współbieżne

Semafor nie jest mechanizmem strukturalnym. Aplikacje pisane z użyciem semaforów są podatne na błędy. Np. brak operacji sem_post blokuje aplikację.

Programowanie aplikacji równoległych i rozproszonych. Wykład 1

Systemy operacyjne III

Systemowe mechanizmy synchronizacji procesów

Mechanizmy komunikacji. spotkania symetryczne (język CSP) spotkania asymetryczne (Ada) przestrzenie krotek (Linda) potoki, komunikaty i kanały (Unix)

SYSTEMY CZASU RZECZYWISTEGO - VxWorks

WYKŁAD 4 SEMAPHORES (CIĄG DALSZY) Przykład 6 Problem czytelników i pisarzy. Wykład 4 strona 1/24

Klasyczne problemy współbieżności. Problem producenta i konsumenta Problem czytelników i pisarzy Problem pięciu filozofów

Wprowadzenie do programowania współbieżnego

9. Problem wzajemnego wykluczania i sekcji krytycznej

Programowanie Współbieżne

Proces z sekcją krytyczną. Synchronizacja procesów. Synchronizacja procesów, cd. Synchronizacja procesów, cd. Synchronizacja procesów, cd

Programowanie współbieżne Wykład 7. Iwona Kochaoska

Synchronizacja procesów

Implementacje zgodne z tym standardem są nazywane wątkami POSIX lub Pthreads.

Przeplot. Synchronizacja procesów. Cel i metody synchronizacji procesów. Wątki współbieżne

Równoległość i współbieżność

Równoległość i współbieżność

Dzisiejszy wykład. Klasa string. wersja prosta wersja ze zliczaniem odwołań. Wyjątki Specyfikator volatile Semafory

procesów Współbieżność i synchronizacja procesów Wykład prowadzą: Jerzy Brzeziński Dariusz Wawrzyniak

Programowanie współbieżne Wykład 9 Synchronizacja dostępu do współdzielonych zasobów. Iwona Kochańska

Podstawy programowania współbieżnego. 1. Wprowadzenie. 2. Podstawowe pojęcia

PROGRAMOWANIE SYSTEMÓW CZASU RZECZYWISTEGO

Systemy Operacyjne synchronizacja i komunikacja procesów

Ingerencja w kod systemu operacyjnego (przerwania) Programowanie na niskim poziomie (instrukcje specjalne) Trudności implementacyjne (alg.

Problemy czytelników i pisarzy oraz 5 ucztujących filozofów

Programowanie współbieżne Wykład 5. Rafał Skinderowicz

procesy odrębne dzielone

Systemy Operacyjne 2: Wątki pthreads. dr inż. Arkadiusz Chrobot

Współbieżność i równoległość w środowiskach obiektowych. Krzysztof Banaś Obliczenia równoległe 1

Semafory. - aktywne oczekiwanie =GRGDWNRZ\PZVSDUFLHPVSU]WRZ\P 6SHFMDOQDLQVWUXNFMDPDV]\QRZDUHDOL]XMFDDWRPRZ\]DSLVL odczyt, np.

Jędrzej Ułasiewicz Programownie aplikacji współbieżnych str. 1. Wątki

Programowanie wielowątkowe. Tomasz Borzyszkowski

Tworzenie wątków. #include <pthread.h> pthread_t thread;

Wątek - definicja. Wykorzystanie kilku rdzeni procesora jednocześnie Zrównoleglenie obliczeń Jednoczesna obsługa ekranu i procesu obliczeniowego

Języki i Techniki Programowania II. Wykład 7. Współbieżność 1

5. Model komunikujących się procesów, komunikaty

Program jest więc strukturą statyczną zapisaną na jakimś nośniku. Natomiast proces jest wykonującym się programem.

4.2 Sposób korzystania z l acza

Zaawansowane programowanie w C++ (PCP)

Program współbieżny jest zbiorem sekwencyjnych PROGRAMOWANIE C++

Systemy operacyjne Wzajemne wykluczanie i synchronizacja

Przykład wystąpienia wyścigu. Systemy operacyjne / Wzajemne wykluczanie i synchronizacja str.4/33. Wyścigi w systemie operacyjnym.

Mechanizmy pracy równoległej. Jarosław Kuchta

Wykład 3. Procesy i wątki. Wojciech Kwedlo, Wykład z Systemów Operacyjnych -1- Wydział Informatyki PB

Proces z sekcją krytyczną. Synchronizacja procesów. Synchronizacja procesów, cd. Synchronizacja procesów, cd. Synchronizacja procesów, cd

Synchronizacja procesów

Współbieżność w środowisku Java

Podstawy programowania w języku C

Problem producentakonsumenta

POSIX: IEEE Std (Issue 6, 2004 edition)

Systemy operacyjne. Studia podyplomowe Wydział Informatyki PB

SYSTEMY OPERACYJNE WYKLAD 6 - procesy

Od uczestników szkolenia wymagana jest umiejętność programowania w języku C oraz podstawowa znajomość obsługi systemu Linux.

4. Procesy pojęcia podstawowe

Klient-Serwer Komunikacja przy pomocy gniazd

METODY I JĘZYKI PROGRAMOWANIA PROGRAMOWANIE STRUKTURALNE. Wykład 02

Zadanie 1 Przygotuj algorytm programu - sortowanie przez wstawianie.

TABLICE W JĘZYKU C/C++ typ_elementu nazwa_tablicy [wymiar_1][wymiar_2]... [wymiar_n] ;

Co nie powinno być umieszczane w plikach nagłówkowych:

Mogą pracować w środowisku: Scentralizowanym -mikrokontroler Rozproszonym sieć sterująca, systemy hierarchiczne. Komunikacja z syst.

Transkrypt:

Problemy współbieżności

wyścig (race condition) synchronizacja realizowana sprzętowo (np. komputery macierzowe) realizowana programowo (bariera, sekcja krytyczna, operacje atomowe) wzajemne wykluczanie sekcja krytyczna protokoły wejścia i wyjścia z sekcji krytycznej cechy rozwiązań zagadnień synchronizacji: pożądane bezpieczeństwo i żywotność, uczciwość możliwe błędy - zakleszczenie, zagłodzenie

Zamki (locks, sygnalizatory dostępu, blokady) int zamek=0; procedura_wątek(){ while (zamek!= 0) { // aktywne czekanie (busy wait) zamek = 1; sekcja_krytyczna(); zamek = 0; Problemy: aktywne czekanie zużywa zasoby komputera procedura nie jest bezpieczna ani nie zapewnia żywotności

Semafory semafor jest zmienną globalną, na której można dokonywać dwóch niepodzielnych, wykluczających się operacji, zwyczajowo nazywanych: P (probeer, wait) i V (verhoog, signal) P i V często są zaimplementowane w jądrze systemu operacyjnego, gdyż zawierają operacje atomowe P( int s ){ if( s>0 ) s--; else uśpij_wątek(); V( int s ) { if( ktoś_śpi() ) obudź_wątek(); else s++; inicjacja semafora, np. init( int s, int v ) { s=v; semafory umożliwiają poprawne rozwiązanie problemu wzajemnego wykluczania implementacja V decyduje o uczciwości semafora (np. FIFO) wartość s oznacza liczbę dostępów do zasobu np. semafor binarny

Problem producentów i konsumentów Problem czytelników i pisarzy Problem ucztujących filozofów

Procesy współdzielą bufor dla produkowanych jednostek. Producent tworzy produkt i umieszcza w buforze. Konsument pobiera produkt z bufora Problem: Jak nie doprowadzić do przepełnienia bufora oraz zapobiec zagłodzeniu konsumenta?

Rozwiązanie: int sem_pełny = 0; int sem_pusty = ROZMIAR_BUFORA; void producent() { while (true) { produkuj(produkt); P(sem_pusty); //zmniejsza dodajproduktdobufora(produkt); V(sem_pełny); //zwiększa

Rozwiązanie: void konsument() { while (true) { P(sem_pełny); //zmniejsza pobierzproduktzbufora(produkt); V(pusty); //powiększa konsumuj (produkt)

Procesy czytające i piszące Czytelnicy jednoczesny dostęp do zasobu Pisarze wyłączny dostęp do zasobu brak dostępu dla innego pisarza oraz dla czytelników Problem jak nie zagłodzić czytelników ani pisarzy? Rozwiązanie: Scheduling kolejka FIFO

Dla 5ciu filozofów: filozof: albo je, albo myśli filozofowie siedzą przy stole, każdy ma talerz, pomiędzy każdymi dwoma talerzami leży widelec na środku stołu stoi misa z spaghetti problem polega na tym, że do jedzenia spaghetti potrzebne są dwa widelce (po obu stronach talerza) jak zapewnić przeżycie filozofom? Źródło: Benjamin D. Esham / Wikimedia Commons, CC BY-SA 3.0, https://commons.wikimedia.org/w/index.php?curid=56559

rozwiązanie proste dopuszczające blokadę (niepoprawne) widelec[i], i=0..4 //pięć semaforów binarnych dla pięciu //widelców (zainicjowanych wartością 1) wątek_filozof (int i) { //procedura dla i-tego filozofa (pięć współbieżnie //realizowanych wątków, i=0..4) for(;;) { myśl(); wait(widelec[i]); wait(widelec[(i+1) mod 5]); jedz(); signal(widelec[i]); signal(widelec[(i+1) mod 5]);

rozwiązanie poprawne, nieco bardziej skomplikowane widelec[i], i=0..4 //pięć semaforów binarnych dla pięciu //widelców (zainicjowanych wartością 1) pozwolenie //semafor poczwórny (=4) wątek_filozof (int i) { //procedura dla i-tego filozofa (pięć współbieżnie //realizowanych wątków, i=0..4) for(;;) { myśl(); wait(pozwolenie); wait(widelec[i]); wait(widelec[(i+1) mod 5]); jedz(); signal(widelec[i]); signal(widelec[(i+1) mod 5]); signal(pozwolenie);

Specyfikacja POSIX: muteks mutual exclusion tworzenie muteksa int pthread_mutex_init (pthread_mutex_t *mutex, const pthread_mutex attr_t *mutexattr) zamykanie muteksa (istnieje wersja pthread_mutex_trylock) int pthread_mutex_lock (pthread_mutex_t *mutex) otwieranie muteksa int pthread_mutex_unlock (pthread_mutex_t *mutex) odpowiedzialność za poprawne użycie muteksów (gwarantujące bezpieczeństwo i żywotność) spoczywa na programiście

#include<pthread.h> #define LICZBA 100 #define LICZBA_W 4 pthread_mutex_t muteks; int suma=0; pthread_t watki[liczba_w]; int main( int argc, char *argv[] ) { int i, indeksy[liczba_w]; for(i=0;i<liczba_w;i++) indeksy[i]=i; pthread_mutex_init( &muteks, NULL); for(i=0; i<liczba_w; i++ ) pthread_create( &watki[i], NULL, suma_w, (void *) &indeksy[i] ); for(i=0; i<liczba_w; i++ ) pthread_join( watki[i], NULL ); printf( suma = %d\n,suma);

void *suma_w (void *arg_wsk) { int i, moj_id, moja_suma=0; moj_id = *( (int *) arg_wsk ); j=liczba/liczba_w; for( i=j*moj_id+1; i<=j*(moj_id+1); i++) { moja_suma += i; pthread_mutex_lock( &muteks ); suma += moja_suma; pthread_mutex_unlock( &muteks ); pthread_exit( (void *)0 );

Zmienne warunku condition variables: zmienne warunku są zmiennymi wspólnymi dla wątków, które służą do identyfikacji grupy uśpionych wątków tworzenie zmiennej warunku: int pthread_cond_init( pthread_cond_t *cond, pthread_condattr_t *cond_attr ) uśpienie wątku w miejscu identyfikowanym przez zmienną warunku cond, wątek śpi (czeka) do momentu, gdy jakiś inny wątek wyśle odpowiedni sygnał budzenia dla zmiennej cond int pthread_cond_wait( pthread_cond_t *cond, pthread_mutex_t *mutex ) sygnalizowanie (budzenie pierwszego oczekującego na zmiennej *cond) int pthread_cond_signal( pthread_cond_t *cond ) rozgłaszanie sygnału (budzenie wszystkich oczekujących na zmiennej *cond) int pthread_cond_broadcast( pthread_cond_t *cond)

Schemat rozwiązania problemu producenta i konsumenta pthread_mutex_t muteks=pthread_mutex_initializer; pthread_cond_t nie_pelna, nie_pusta; // należy także // zainicjować int main() { pthread_t producent, konsument; kolejka *fifo; fifo = inicjuj_kolejka(); // kolejka zawiera bufor do zapisu i odczytu pthread_create( &producent, NULL, produkuj, fifo ); pthread_create( &konsument, NULL, konsumuj, fifo ); pthread_join( producent, NULL); pthread_join( konsument, NULL );

procedura producenta void *produkuj( void *q) { kolejka *fifo; int i; fifo = (kolejka *)q; for(...) { pthread_mutex_lock ( &muteks); while( kolejka_pelna(fifo) ) pthread_cond_wait( &nie_pelna, &muteks ); kolejka_wstaw(fifo,...); pthread_mutex_unlock( &muteks ); pthread_cond_signal( &nie_pusta );

procedura konsumenta void *konsumuj( void *q) { kolejka *fifo; int i, d; fifo = (kolejka *)q; for(...) { pthread_mutex_lock (&muteks); while( kolejka_pusta(fifo) ) pthread_cond_wait(&nie_pusta, &muteks); kolejka_pobierz(fifo,...); pthread_mutex_unlock( &muteks ); pthread_cond_signal( &nie_pelna );

Zależności wzajemne uzależnienie instrukcji nakładające ograniczenia na kolejność ich realizacji Zależności zasobów kiedy wiele wątków jednocześnie usiłuje korzystać z wybranego zasobu (np. pliku)

Zależności sterowania kiedy wykonanie danej instrukcji zależy od rezultatów poprzedzających instrukcji warunkowych Zależności danych (zależności przepływu) kiedy instrukcje wykonywane w bezpośrednim sąsiedztwie czasowym operują na tych samych danych i choć jedna z tych instrukcji dokonuje zapisu

1 if (a==b) 2 a = a + b; 3 b = a + b; Linijka 2 kontroluje warunek w linijce 1, linijka 3 wykona się zawsze bez względu na wynik warunku 1.

Struktura danych używana przez kompilator do reprezentacji procedur w programie. Wierzchołkami są bloki podstawowe a krawędzie pokazują powiązania między blokami.

Front dominacji

zależności wyjścia (zapis po zapisie, write-afterwrite) a :=... a :=... Zależności wyjścia nie są rzeczywistym problemem; odpowiednia analiza kodu może doprowadzić do wniosku o możliwej eliminacji instrukcji lub przemianowaniu zmiennych

Problem: x=4; y=x+2; x=5; Rozwiązanie: x2=4; y=x2+2; x=5;

anty-zależności (zapis po odczycie, write-afterread)... := a a :=... także tutaj odpowiednie przemianowanie zmiennych może zlikwidować problem

Problem: x=4; y=x+2; x=5; Rozwiązanie: x=4; x2 = x; y=x2+2; x=5;

zależności rzeczywiste (odczyt po zapisie, readafter-write) a :=...... := a zależności rzeczywiste uniemożliwiają zrównoleglenie algorytmu konieczne jest jego przeformułowanie w celu uzyskania wersji możliwej do zrównoleglenia

x=5; y=x; z=y; Każda instrukcja zależy od poprzedniej!

Wszystkie powyższe zależności mogą występować albo jawnie jak w podanych przykładach, lub niejawnie jako tzw. zależności przenoszone przez pętle

Zależności w kodzie: 1. x = 2*y + w; 2. y = 2*z cos(w); 3. z = log(w) + y; 4. x += sin(z); 5. w = 5*y; x: 1-4 -> WAW y: 1-2 -> WAR, 2-3 -> RAW, 2-5 -> RAW z: 2-3 -> WAR, 3-4 -> RAW w: 1-5 -> WAR, 2-5 ->WAR, 3-5 -> WAR

Możliwe zrównoleglenie usunięcie zależności narzut wykonania równoległego Przykłady zależności przenoszonych w pętli zrównoleglenie narzut wykonania równoległego poprawność zależna od operacji w skrajnych iteracjach

zależności wyjścia (output dependencies) ewentualne zrównoleglenie działania po przemianowaniu zmiennych musi zachować kolejność zapisu danych anty-zależności (anti-dependencies) możliwe zrównoleglenie działania poprzez przemianowanie zmiennych zależności rzeczywiste (true dependencies) W przypadku użycia wskaźników automatycznie zrównoleglające kompilatory mogą podejrzewać występowanie utożsamienia (zamienności) nazw (aliasing)

zależności wyjścia for(j = 0; j < n; j++) { c[j] = j; c[j+1] = 5; anty-zależności for(j = 0; j < n; j++) b[j] = b[j+1];

zależności rzeczywiste (true dependencies) for(j = 0; j < n; j++) a[j] = a[j-1]; Zależności przenoszone przez pętle for(i = 0; i < 4; i++) { b[i] = 8; a[i] = b[i-1] + 10; for(i = 0; i < 4; i++) { b[i] = 8; a[i] = b[i] + 10;

Zależności przenoszone przez pętle for(i = 0; i < 4; i++) for(j = 0; j < 4; j++) a[i][j] = a[i][j-1] * x;

W celu przeprowadzenia analizy zależności w programie można konstruować i badać grafy zależności Dla praktycznie występujących programów konstrukcja i analiza grafu zależności przekracza możliwości komputerów (problem jest NP-trudny) Kompilatory zrównoleglające stosują rozmaite metody heurystyczne analizy kodu W wielu wypadkach analiza nie powodzi się (zwłaszcza, gdy np. poszczególne wątki wywołują procedury) Ingerencja projektanta algorytmu i programisty okazuje się być często jedynym sposobem na uzyskanie efektywnego programu równoległego

Dziękuję za uwagę