Ak ste už zvládli prípravu prostredia a viete ako komunikovať s interpreterom jazyka Python, môžete sa pustiť do cvičenia. Otvorte prostredie IDLE
a zvoľte z ponuky File
položku New File
. Otvorí sa vám ďalšie okno, v ktorom môžete písať sled príkazov jazyka Python. Najprv si súbor uložte (Ctrl+S
). Odporúčame, aby ste si vo vašom priečinku (C:\work\<login_do_ais>
) vytvorili podpriečinok pre naše cvičenia. Do neho si uložte tento súbor. Po zvládnutí vytvorenia a uloženia súboru môžete spokojne pokračovať v písaní programov. Počas semestra nebudeme pre potreby výučby používať iné vývojové prostredie než IDLE
(samozrejme, vy môžete používať svoj obľúbený textový editor alebo IDE). Ak chceme spustiť z prostredia IDLE
náš skript, stlačíme tlačidlo F5
(alebo pomocou navigácie Run->Run Module
). Kto ešte v Pythone neprogramoval, nech si preštuduje kapitolu http://howto.py.cz/cap04.htm s názvom ‚Podmínky a funkce‘. Mali by ste (okrem iných) vypracovať úlohy 4–7 z Cvičení (časť 4.10). Venujte tomu maximálne 30 minút, potom pokračujte vypracovaním nasledovného zadania (pomocou modulu ppds
).
Implementujte dve vlákna, ktoré budú používať spoločný index do spoločného poľa (inicializovaného na hodnoty 0) istej veľkosti. Každé vlákno nech inkrementuje ten prvok poľa, kam práve ukazuje spoločný index. Následne nech index zvýši. Ak už index ukazuje mimo poľa, vlákno svoju činnosť skončí. Po skončení vlákien spočítajte, koľko prvkov poľa má hodnotu 1. Ak zistíte, že nie každý prvok poľa má hodnotu 1, modifikujte program tak, aby na koniec (po skončení behu vlákien) zistil početnosti (histogram) hodnôt, ktoré sa nachádzajú v poli. Pre zjednodušenie úlohy prikladáme nasledovné poznámky.
ppds
. Shared
, ktorý bude mať nasledovné atribúty (nastavujte ich v inicializačnej funkcii triedy):
counter
end
elms
o veľkosti end
s vynulovanými prvkami shared
. Túto funkciu budú vykonávať pracovné vlákna. Funkcia nech v nekonečnom cykle v každej iterácii:
shared.counter
nie je mimo veľkosti poľa; ak áno, cyklus sa preruší a funkcia skončí shared.elms
na pozícii shared.counter
shared.counter
shared
o veľkosti poľa napríklad 1 000 000 Vytvorenie a čakanie na dokončenie behu vlákna pomocou modulu ppds
, skelet programu:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 |
# nacitame triedu Thread z modulu 'fei.ppds' from fei.ppds import Thread # definicia triedy 'Shared' class Shared(): pass # definicia funkcie vlakna def fnc_test(shared): pass # vytvorenie instancie triedy 'Shared' shared = Shared(1_000_000) # do 't1' ulozime identifikator pracovneho vlakna # prvy argument pri vytvarani objektu typu 'Thread' je funkcia, ktoru ma # vlakno vykonavat # dalsie argumenty sa predaju funkcii, ktora je definovana prvym argumentom t1 = Thread(fnc_test, shared) # pockame na dokoncenie behu vlakna t1.join() |
Ak chceme opraviť program a použiť synchronizačný vzor ‚Mutual Exclusion‘, na implementáciu mutexu môžeme použiť triedu Mutex
z modulu ppds
. Ukážka použitia:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
from ppds import Mutex, Thread def fnc_vlakno(mutex): mutex.lock() # kriticka oblast mutex.unlock() # vytvor mutex mutex = Mutex() # vytvor a spusti vlakna # pockaj na ich dokoncenie # ... |
Je potrebné si uvedomiť, že sa jedná o ukážku použitia mutexu/zámku v kóde. A je načase začať uvažovať, kam všade je možné (alebo skôr má zmysel) umiestniť zámok a aké to má dôsledky pre konkurentné/paralelné vykonávanie kódu.
Na domácu úlohu skúste vytvoriť tri variácie použitia zámku v kóde na rôznych miestach (aby bolo použitie zámku syntakticky aj sémanticky správne!) a do dokumentácie riešení uveďte, aký vplyv má dané umiestnenie zámku na vykonávanie kódu (z pohľadu paralelného programovania, ovšem; pozor, nech váš úsudok neovplyvní GIL!).
Vo svojom repozitári vytvorte vetvu s príslušným názvom pre prvé cvičenie a v rámci tejto vetvy implementujte svoje tri riešenia, každé riešenie v samostatnom súbore. Dokumentácia musí byť súčasťou repozitára v príslušnej štruktúre .md súborov. Dodržte PEP8 pre štruktúru programového kódu (štábnu kultúru) a komentárov. Každý modul a každá funkcia (trieda, metóda) musí byť riadne dokumentovaná. Ak kód nie je dobre čitateľný a potrebuje vysvetlenie, tak musí byť komentovaný. Commit správy musia byť v súlade s CC.