• Nie Znaleziono Wyników

ProgramowaniewspółbieżneZadanie5-Podstawoweproblemyprogramowaniawspółbieżnego Semestr 7 Rokakademicki 2011/12 Specjalizacja InżynieriaOprgoramowaniaiAnalizaDanych Kierunek Informatyka Data 2011-11-07

N/A
N/A
Protected

Academic year: 2021

Share "ProgramowaniewspółbieżneZadanie5-Podstawoweproblemyprogramowaniawspółbieżnego Semestr 7 Rokakademicki 2011/12 Specjalizacja InżynieriaOprgoramowaniaiAnalizaDanych Kierunek Informatyka Data 2011-11-07"

Copied!
9
0
0

Pełen tekst

(1)

150875

numer indeksu Grzegorz Graczyk

imię i nazwisko

151021

numer indeksu Paweł Tarasiuk

imię i nazwisko

Data 2011-11-07

Kierunek Informatyka

Specjalizacja Inżynieria Oprgoramowania i Analiza Danych Rok akademicki 2011/12

Semestr 7

Programowanie współbieżne

Zadanie 5 - Podstawowe problemy

programowania współbieżnego

(2)

Wstęp

Zadanie laboratoryjne polegało na implementacji problemu czytelników i pisarzy. Czytelnicy i pisarze rywalizują o dostęp do tego samego zasobu. W tym samym czasie z zasobu może korzystać dowolna liczba czytelników albo dokładnie jeden pisarz.

Rozwiązanie

W ramach rozwiązania została stworzona klasa RWLock, która posiada metody pozwalające oddzielić kod samych czytelników i pisarzy od samej implementacji rozwiązania problemu. Dzięki temu raz napisany program testujący może być testowany na różnych implementacjach.

Przygotowaliśmy trzy propozycje rozwiązania problemu (czyli odmienne implementacje klasy RWLock):

Rozwiązanie wstępne

Rozwiązanie to wykorzystuje jeden monitor oraz zamek powiązany z tym monitorem. Moż- liwa jest również implementacja w oparciu o dwa semafory. Czytelnicy zamykają zamek jedynie na czas rozpoczynania i kończenia czytania. Procedury te są sekcjami krytycznymi, a w ich czasie jest modyfikowany licznik czytelników. W wypadku pisarzy zamek jest zakładany w chwi- li rozpoczęcia pisania. Następnie dopóki istnieją czytelnicy zamek jest otwierany, zaś procesy zatrzymują się na monitorze w oczekiwaniu aż licznik czytelników zostanie wyzerowany. Po za- kończeniu oczekiwania proces zamyka zamek i otwiera go po zakończeniu pisania.

Rozwiązanie to jest poprawne (w sensie poprawnego ograniczenia dostępu do zasobu) oraz nie zawiera blokad. Nie rozwiązuje ono jednak w żaden sposób problemu zagłodzenia.

PSK: Grzegorz Graczyk i Paweł Tarasiuk 2 / 9

(3)

Rozwiązanie z priorytetem dla pisarzy

Do powyższego rozwiązania dodajemy licznik oczekujących pisarzy, który będzie zabloko- wany nowym zamkiem. Od tej chwili każdy czytelnik przed zwiększeniem licznika czytelników upewnia się, że żaden pisarz nie czeka. W przeciwnym wypadku czytelnik zatrzymuje się na monitorze do czasu zakończenia pracy wszystkich pisarzy.

Rozwiązanie to rozbudowuje poprzednie rozwiązanie o optymalne wykorzystanie czasu. Dzię- ki temu do zagłodzenia dochodzi tylko w wypadku, gdy nowi pisarze pojawiają się szybciej niż starzy kończą swoje zadania.

PSK: Grzegorz Graczyk i Paweł Tarasiuk 3 / 9

(4)

Rozwiązanie z priorytetem dla oczekujących pisarzy

Rozwiązaniem, które naszym zdaniem najlepiej pozbywa się problemu zagłodzenia jest mody- fikacja powyższego. Tym razem priorytet jest przyznawany tym pisarzom, którzy czekali w trak- cie czytania dowolnego czytelnika. W celu realizacji tej metody licznik pisarzy jest zwiększany dopiero po spełnieniu warunku zmiany licznika czytelników. Pewnym uproszczeniem w stosun- ku do poprzedniego rozwiązania jest fakt, że czytelnicy po otrzymaniu sygnału na monitorze o obsłużeniu wszystkich pisarzy z priorytetem nie upewniają się czy nie pojawił się nowy pisarz.

PSK: Grzegorz Graczyk i Paweł Tarasiuk 4 / 9

(5)

Implementacja

Rozwiązania zostały wykonane w języku Python, z wykorzystaniem biblioteki multipro- cessing. W implementacji wykorzystywany jest fakt, iż logika monitorów znajduje się w kla- sie Condition odpowiadającej warunkowi monitora. Faktycznym elementem odpowiadającym monitorowi jest klasa Lock, której instancja jest parametrem konstruktora obiektu warunku.

W efekcie implementacja zawiera jedynie jeden zamek co zmniejsza ryzyko popełnienia przez programistę błędu prowadzącego do blokady.

Wątkami są czytelnicy oraz pisarze. Ponadto istnieje dodatkowy wątek służący tworzeniu czytelników i pisarzy za pomocą interfejsu graficznego. Interfejs pozwala śledzić stan czytelników i pisarzy - zmiany w tym stanie świadczą o tym, komu po kolei przydzielany jest zasób.

Interfejs okienkowy został wykonany w oparciu o bidingi biblioteki gtk dla języka Python.

Podsumowanie

Problem czytelników i pisarzy można rozwiązywać na wiele sposobów, a ocena które z tych sposobów są lepsze nie jest uniwersalna - wszystko zależy od oczekiwań co do priorytetu pomię- dzy czytelnikami a pisarzami. Przygotowane przez nas rozwiązanie z priorytetem dla pisarzy jest popularnym podejściem do problemu, lecz pomysł będący podstawą trzeciej spośród przygotowa- nych przez nas propozycji rozwiązania stanowi pewien kompromis pomiędzy znaczeniem pisarzy (którzy powinni jak najszybciej aktualizować zasób), a unikaniem zagłodzenia czytelników.

PSK: Grzegorz Graczyk i Paweł Tarasiuk 5 / 9

(6)

Kod programu

Kod głównej części programu

#! / u s r / b i n / env python

# −∗− c o d i n g : u t f −8 −∗−

# c o n f i g :

w r i t e r s p r i o r i t y = F a l s e c l i c k r e q u i r e d = True

e n t r y t i m e = 1

w o r k i n g t i m e = 1

l e a v i n g t i m e = 1

i m p o r t p yg tk

p yg tk . r e q u i r e (’ 2 . 0 ’) i m p o r t gtk , g o b j e c t

from m u l t i p r o c e s s i n g i m p o r t P r o c e s s a s Th re a dO rP r oc es s , Queue , Semaphore from t i m e i m p o r t s l e e p

i f w r i t e r s p r i o r i t y == True : p r i n t ’ P r i o r y t e t p i s a r z y ’ from p r w l o c k i m p o r t RWLock e l i f w r i t e r s p r i o r i t y == F a l s e :

p r i n t ’ Bez p r i o r y t e t u ’ from r w l o c k i m p o r t RWLock e l s e:

p r i n t ’ P r i o r y t e t o c z e k u j a c y c h p i s a r z y ’ from x r w l o c k i m p o r t RWLock

d e f a s y n c ( f u n c t i o n ) :

d e f C a l l ( ∗ a r g s , ∗ ∗ kwargs ) :

t = T h r e a d O r P r o c e s s ( t a r g e t=f u n c t i o n , a r g s=a r g s ) t . daemon = kwargs . g e t (’ daemon ’, True )

t . s t a r t ( ) r e t u r n t r e t u r n C a l l

l a b e l q u e u e = Queue ( ) r e s o u r c e = RWLock ( )

@async

d e f Reader ( i , s ) :

l a b e l q u e u e . put ( ( i , ” C z y t e l n i k %d . [ ] ” % i ) ) s l e e p ( e n t r y t i m e )

r e s o u r c e . a c q u i r e R e a d ( )

l a b e l q u e u e . put ( ( i , ” C z y t e l n i k %d . [ x ] ” % i ) ) s l e e p ( w o r k i n g t i m e )

i f c l i c k r e q u i r e d : s . a c q u i r e ( )

r e s o u r c e . r e l e a s e R e a d ( )

l a b e l q u e u e . put ( ( i , ”<− C z y t e l n i k %d . ” % i ) ) s l e e p ( l e a v i n g t i m e )

l a b e l q u e u e . put ( ( i , None ) )

@async

d e f W r i t e r ( i , s ) :

l a b e l q u e u e . put ( ( i , ” [ ] P i s a r z %d . ” % i ) ) s l e e p ( e n t r y t i m e )

r e s o u r c e . a c q u i r e W r i t e ( )

l a b e l q u e u e . put ( ( i , ” [ x ] P i s a r z %d . ” % i ) ) s l e e p ( w o r k i n g t i m e )

i f c l i c k r e q u i r e d : s . a c q u i r e ( )

r e s o u r c e . r e l e a s e W r i t e ( )

l a b e l q u e u e . put ( ( i , ” P i s a r z %d . −>” % i ) ) s l e e p ( l e a v i n g t i m e )

l a b e l q u e u e . put ( ( i , None ) )

PSK: Grzegorz Graczyk i Paweł Tarasiuk 6 / 9

(7)

################################# GUI ################################

c l a s s Window :

d e f u p d a t e l a b e l s ( s e l f ) :

w h i l e n o t l a b e l q u e u e . empty ( ) : i , l a b e l = l a b e l q u e u e . g e t ( ) i f l a b e l i s None :

s e l f . b u t t o n s [ i ] . d e s t r o y ( ) e l s e:

s e l f . b u t t o n s [ i ] . s e t l a b e l ( l a b e l ) g o b j e c t . t i m e o u t a d d ( 1 0 , s e l f . u p d a t e l a b e l s )

d e f n e w b u t t o n ( s e l f , box , t e x t , t a s k ) :

btn = g t k . Button (”Nowy %s ” % t e x t . l o w e r ( ) )

btn . c o n n e c t (” c l i c k e d ”, s e l f . n e w c l i c k e d , ( box , t a s k ) ) btn . s e t s i z e r e q u e s t ( 2 5 0 , 5 0 )

box . p a c k e n d ( btn , F a l s e , F a l s e ) btn . show ( )

d e f b u t t o n ( s e l f , box , s ) : btn = g t k . Button ( )

btn . c o n n e c t (” c l i c k e d ”, s e l f . c l i c k e d , ( s ) ) btn . s e t s i z e r e q u e s t ( 2 5 0 , 5 0 )

box . p a c k s t a r t ( btn , F a l s e , F a l s e ) btn . show ( )

r e t u r n btn

d e f n e w c l i c k e d ( s e l f , w i d g e t , d a t a=None ) : box , Task = d a t a

i = l e n ( s e l f . b u t t o n s ) s = Semaphore ( 0 )

s e l f . b u t t o n s += [ s e l f . b u t t o n ( box , s ) ] Task ( i , s )

d e f c l i c k e d ( s e l f , w i d g e t , d a t a=None ) : d a t a . r e l e a s e ( )

d e f d e l e t e e v e n t ( s e l f , w i d g e t , e v e n t , d a t a=None ) : r e t u r n F a l s e

d e f d e s t r o y ( s e l f , w i d g e t , d a t a=None ) : g t k . m a i n q u i t ( )

d e f i n i t ( s e l f ) : s e l f . b u t t o n s = [ ]

s e l f . window = g t k . Window ( g t k .WINDOW TOPLEVEL)

s e l f . window . c o n n e c t (” d e l e t e e v e n t ”, s e l f . d e l e t e e v e n t ) s e l f . window . c o n n e c t (” d e s t r o y ”, s e l f . d e s t r o y )

s e l f . window . s e t b o r d e r w i d t h ( 5 ) c o n t e n t = g t k . HBox ( )

l e f t = g t k . VBox ( )

l e f t . s e t b o r d e r w i d t h ( 5 )

s e l f . n e w b u t t o n ( l e f t , ” C z y t e l n i k ”, Reader )

c o n t e n t . add ( l e f t ) l e f t . show ( )

s e p = g t k . V S e p a r a t o r ( ) c o n t e n t . add ( s e p ) s e p . show ( )

r i g h t = g t k . VBox ( )

r i g h t . s e t b o r d e r w i d t h ( 5 )

s e l f . n e w b u t t o n ( r i g h t , ” P i s a r z ”, W r i t e r ) c o n t e n t . add ( r i g h t )

r i g h t . show ( )

s e l f . window . add ( c o n t e n t )

PSK: Grzegorz Graczyk i Paweł Tarasiuk 7 / 9

(8)

c o n t e n t . show ( ) s e l f . window . show ( )

d e f main ( s e l f ) :

g o b j e c t . t i m e o u t a d d ( 1 0 0 0 , s e l f . u p d a t e l a b e l s ) g t k . main ( )

Window ( ) . main ( )

Kod rozwiązania najprostszego

from m u l t i p r o c e s s i n g i m p o r t Lock , Value , C o n d i t i o n

c l a s s RWLock :

d e f i n i t ( s e l f ) : s e l f . l o c k = Lock ( )

s e l f . c o n d i t i o n = C o n d i t i o n ( s e l f . l o c k ) s e l f . r e a d e r s = Value (’ i ’, 0 , l o c k=F a l s e )

d e f a c q u i r e R e a d ( s e l f ) : s e l f . l o c k . a c q u i r e ( ) s e l f . r e a d e r s . v a l u e += 1 s e l f . l o c k . r e l e a s e ( )

d e f a c q u i r e W r i t e ( s e l f ) : s e l f . l o c k . a c q u i r e ( )

w h i l e s e l f . r e a d e r s . v a l u e > 0 : s e l f . c o n d i t i o n . w a i t ( )

d e f r e l e a s e R e a d ( s e l f ) : s e l f . l o c k . a c q u i r e ( ) s e l f . r e a d e r s . v a l u e −= 1 i f s e l f . r e a d e r s . v a l u e == 0 :

s e l f . c o n d i t i o n . n o t i f y a l l ( ) s e l f . l o c k . r e l e a s e ( )

d e f r e l e a s e W r i t e ( s e l f ) : s e l f . l o c k . r e l e a s e ( )

Kod rozwiązania z priorytetem czytelników

from m u l t i p r o c e s s i n g i m p o r t Lock , Value , C o n d i t i o n

c l a s s RWLock :

d e f i n i t ( s e l f ) : s e l f . l o c k = Lock ( )

s e l f . c o n d i t i o n = C o n d i t i o n ( s e l f . l o c k ) s e l f . r e a d e r s = Value (’ i ’, 0 , l o c k=F a l s e )

s e l f . w c o n d i t i o n = C o n d i t i o n ( s e l f . l o c k ) s e l f . w r i t e r s = Value (’ i ’, 0 )

d e f a c q u i r e R e a d ( s e l f ) : s e l f . l o c k . a c q u i r e ( )

w h i l e s e l f . w r i t e r s . v a l u e > 0 : s e l f . w c o n d i t i o n . w a i t ( ) s e l f . r e a d e r s . v a l u e += 1 s e l f . l o c k . r e l e a s e ( )

d e f a c q u i r e W r i t e ( s e l f ) : s e l f . w r i t e r s . v a l u e += 1 s e l f . l o c k . a c q u i r e ( )

w h i l e s e l f . r e a d e r s . v a l u e > 0 : s e l f . c o n d i t i o n . w a i t ( )

d e f r e l e a s e R e a d ( s e l f ) : s e l f . l o c k . a c q u i r e ( ) s e l f . r e a d e r s . v a l u e −= 1 i f s e l f . r e a d e r s . v a l u e == 0 :

s e l f . c o n d i t i o n . n o t i f y a l l ( )

PSK: Grzegorz Graczyk i Paweł Tarasiuk 8 / 9

(9)

s e l f . l o c k . r e l e a s e ( )

d e f r e l e a s e W r i t e ( s e l f ) : s e l f . w r i t e r s . v a l u e −= 1 i f s e l f . w r i t e r s . v a l u e == 0 :

s e l f . w c o n d i t i o n . n o t i f y a l l ( ) s e l f . l o c k . r e l e a s e ( )

Kod rozwiązania z priorytetem oczekujących czytelników

from m u l t i p r o c e s s i n g i m p o r t Lock , Value , C o n d i t i o n

c l a s s RWLock :

d e f i n i t ( s e l f ) : s e l f . l o c k = Lock ( )

s e l f . c o n d i t i o n = C o n d i t i o n ( s e l f . l o c k ) s e l f . r c o n d i t i o n = C o n d i t i o n ( s e l f . l o c k ) s e l f . r e a d e r s = Value (’ i ’, 0 , l o c k=F a l s e ) s e l f . f i r s t r e a d e r = Value (’ f ’, 0 , l o c k=F a l s e ) s e l f . w r i t e r s = Value (’ i ’, 0 , l o c k=F a l s e )

d e f a c q u i r e R e a d ( s e l f ) : s e l f . l o c k . a c q u i r e ( ) i f s e l f . w r i t e r s :

s e l f . r c o n d i t i o n . w a i t ( ) s e l f . r e a d e r s . v a l u e += 1 s e l f . l o c k . r e l e a s e ( )

d e f a c q u i r e W r i t e ( s e l f ) : s e l f . l o c k . a c q u i r e ( ) f o r c i n g = F a l s e

w h i l e s e l f . r e a d e r s . v a l u e > 0 : s e l f . c o n d i t i o n . w a i t ( ) i f n o t f o r c i n g :

s e l f . w r i t e r s . v a l u e += 1 f o r c i n g = True

i f f o r c i n g :

s e l f . w r i t e r s . v a l u e −= 1 i f s e l f . w r i t e r s . v a l u e == 0 :

s e l f . r c o n d i t i o n . n o t i f y a l l ( )

d e f r e l e a s e R e a d ( s e l f ) : s e l f . l o c k . a c q u i r e ( ) s e l f . r e a d e r s . v a l u e −= 1 s e l f . c o n d i t i o n . n o t i f y a l l ( ) s e l f . l o c k . r e l e a s e ( )

d e f r e l e a s e W r i t e ( s e l f ) : s e l f . l o c k . r e l e a s e ( )

PSK: Grzegorz Graczyk i Paweł Tarasiuk 9 / 9

Cytaty

Powiązane dokumenty

Jako odpowiedź serwer zwraca status skrzynki oraz standardowe odpowiedzi: OK (wykonanie komendy, podanie statusu), NO (brak statusu dla skrzynki o podanej nazwie) lub BAD (złe

Gdy wszystkie bity adresu docelowego mają wartość 1, wówczas komunikat jest typu rozgłoszeniowego i zostaje odebrany przez wszystkie węzły w segmencie.... Podobnie jak dla

Pakiet z odpowiedzią zawiera ustawioną flagę FIN, zatem połączenie jest zakańczane zaraz po jego otrzymaniu (oczywiście po uprzednim wysłaniu pakietu z flagami FIN,ACK oraz

Rozwiązanie oparte jest na definicji iloczynu Cauchy’ego i jest zwykłym mnożeniem macierzy w którym złożoność obliczania każdego pola iloczynu macierzy jest wprost

Gdy na mijance znajduje się jeden pociąg jadący w pewnym kierunku, zaś kolejka pociągów czekających na przejazd w kierunku przeciwnym jest pusta - drugi pociąg jadący w tym

Jeżeli płytka jest podłączona do partu COM, możliwe jest odczytywanie dodatkowych informacji logujących za pomocą przygotowane- go w ramach projektu programu działającego po

Narodowe Święto Niepodległości – święto państwowe w Polsce obchodzone corocznie 11 listopada dla upamiętnienia odzyskania niepodległości przez Polskę w 1918, po 123

[r]