{{indexmenu_n>12}} ====== Lab 12 - Vícevláknové aplikace ====== * Pro vyučující: [[courses:bab36prga:internal:tutorialinstruction:12|]] /* * [[https://docs.google.com/presentation/d/1HBgUYFCPfGIcYmHjLGuv74sXHcbvkpbi0NkpThGVVVE/edit?usp=sharing|Prezentace pro cvičení ]] */ {{ :courses:bab36prga:labs:prga-lab12-sources.zip |Výchozí soubory prga-lab12-sources.zip}}\\ {{ :courses:bab36prga:lectures:bab36prga-lec11-codes.zip |}} ===== Procvičovaná téma ===== * Opakování vláken (pthread) * Implemetace vícevláknové aplikace Cílem cvičení je implementovat program s třemi paralelně běžícími vlákny. První vlákno je určeno pro zpracování vstupu (čtení stiknuté klávesy), druhé vlákno aktualizuje výstup (jednořádkový) a třetí vlákno implementuje časovač, který po uplynutí definované periody zvýší hodnotu proměnné (čítače). Perioda může být nastavována uživatelem, stiskem definovaných kláves. Použití vláken je založeno na knihovně ''pthread'' (POSIX threads) a příklad demonstruje použití základních konstrukcí ''pthread'' knihovny. Úkol na cvičení je implementace aplikace z přednášky [[courses:bab36prga:lectures:start#vicevlaknove_programovani_modely_aplikaci_posix_vlakna_c11_vlakna|lec11]], kterou lze přímo použít. Nicméně postupná a samostatná implementace umožní pochopit principy. Proto postupujte samostatně, což následně může ušetřit čas při implementaci [[courses:bab36prga:hw:hw9|HW 9]] i [[courses:bab36prga:hw:hw9b|HW 9B]]. ===== Úkoly ===== * Použijte bloky z minulého cvičení pro vytvoření aplikace se třemi vlákny. Ve skutečnosti bude mít aplikace vlákna 4, včetně hlavního vlákna ''main()'' funkce * Pro čtení kláves bez nutnosti potvrzovat ''Enter'' přepněte terminál do ''raw'' režimu, například tak jak bylo prezentována v přednášce [[courses:bab36prga:lectures:start#vicevlaknove_programovani_modely_aplikaci_posix_vlakna_c11_vlakna|lec11]]. * Použijte strukturu pro zapouzdření proměnných sdílených jednotlivými vlákny * Použijte kritickou sekci (mutex) pro přístup ke sdíleným datům * Použijte zasílání signálů pro komunikaci mezi vlákny a zabránění plýtvání výpočetním výkonem * Přidejte jméno (textový řetězec) identifikující každé vlákno: "Input", "Output", and "Alarm" * "Alarm" vlákno inkrementálně zvyšuje hodnotu čítače po uplynutí definové periody * Použijte pole a datové struktury, které umožní zautomatizovat správu vláken v cyklech * Program bude reagovat na následující stisk kláves * 'q' - ukončí program tak, že všechna vlákna budou korektně ukončena, tj. vyskočí z příslušných cyklech hlavního těla vlákna * 'r' - sníží periodu pro inkrementaci čítače o 10 ms * 'p' - zvýší periodu pro inkrementaci čítače o 10 ms * Minimální hodnota periody je 10 ms * Maximální hodnota periody je 2000 ms * Výstup programu je jeden řádek ve tvaru "\rAlarm period: %10i Alarm counter: %10i" ==== Tipy ==== * Jelikož výstupní řádek není zakončen koncem řádku může být nutné explicitně vynutit výstup voláním ''flush'' na ''stdout'' ve výstupním vlákně, např. jako fflush(stdout); * Vytvořte novou globální proměnnou ''quit'' k indikaci, že program bude ukončen jakmile uživatel stiskne klávesu ''Enter'' např. bool quit = false; ... gechar(); pthread_mutex_lock(&mtx); quit = true; pthread_mutex_unlock(&mtx); ... ===== Další úkoly na cvičení ===== V další části cvičení pokračujte směrem k implementaci aplikace [[courses:bab36prga:hw:hw9|HW 9 - Vícevláknová aplikace s meziprocesovou komunikací]]. Například program rozdělte na dvě aplikace komunikující pojmenovanou rourou (vizte [[courses:bab36prga:labs:lab10|Lab 10]]). Jedna aplikace může realizovat vláknou pro tisk na obrazovku a druhá aplikace umožní nastavit periodu.