Sčítací monitor s využitím knihovny pthread (vlákna POSIX)

 

Charakteristika příkladu:

 

·        monitor je řešen objektově, tj. jako sada datových prvků a přístupových funkcí (služeb), není ale provedeno explicitní zapouzdření (jazyk C nemá konstrukci class),

·        v hlavním programu se monitor vytvoří (volání sum_ini()) včetně vláken-dělníků,

·        pak lze volat funkci sum_op (&data, ...), kde data je reálné pole, které se má sečíst,

·        funkce vrátí výsledek - součet pole data,

·        uvnitř sum_op() je sčítání provedeno paralelně na principu datového paralelismu , (model SPMD) s dynamickým přidělováním práce vláknům-dělníkům,

·        funkci sum_op() lze z hlavního programu volat opakovaně (jako knihovní fci), pokaždé nad jiným polem data,

·        před ukončením hlavního programu se musí monitor likvidovat voláním fce sum_stop(), jinak  by zůstala neukončená vlákna-dělníci.

 

Rozdíly (většinou zjednodušení) proti analogickému příkladu v jazyce Java:

 

·        monitor není typový, tj. nejde udělat víc instancí,

·        zdrojový kód monitoru je v jednom souboru s hlavním programem,

·        monitor lze využít jen z hlavního programu, tj. není řešena synchronizace přístupu z více vláken-klientů. Samozřejmě musí být řešena synchronizace vláken-dělníků na přístupu k datům obhospodařovaným monitorem,

·        interní operace monitoru (v Javě private metody využívané dělníky) jsou zde zamontovány přímo do kódu dělníků,

·        jsou použity 3 zámky (mutexy) namísto jednoho (skrytého za synchronized) v Javě, ale v zásadě by šel použít též jen jediný (jakoby hlavní) zámek monitoru,

·        při chybě vrátí sum_op() chybový kód, monitor přechází do "nemanipulovatelného stavu" a aplikace se musí "zabít" (včetně jednotlivých vláken).   

 

Náměty na modifikace či vylepšení:

 

·        oddělit monitor do extra souboru (jakoby knihovna),

·        udělat typový monitor - manévry ze základů SW inženýrství, čili zavést datový typ pro data monitoru a do funkcí doplnit ukazatel na instanci datového typu,

·        vylepšit chybovou reakci, tj. při chybě v operaci monitoru se pokusit"zabít vlákna-dělníky". Hlavní program pak může při zjištění chyby v operaci monitoru buď monitor znovu inicializovat nebo organizovaně skončit.

 

Náměty na komplikovanější modifikace pro "opravdové programátory" v C:

 

·        odpustit si předpoklad o využití sčítací operace jen z hlavního programu a řešit synchronizaci více klientů při využití služby (sčítací operace) monitoru - podobně jako je tomu u řešení v Javě.  

·        pokusit se přiblížit možnostem řešení v Adě (využití genericity modulů - generic package) tak, že operand-vektor má prvky libovolného typu (typování void*) a je nad ním volána nějaká obecná redukční operace (reprezentovaná funkcí s daným typem, jejíž jméno se buď importuje při vytváření instance monitoru nebo dosazuje jako parametr volání obecné (generické) redukční operace.  

 

 

Poznámka: Z příkladu (po provedených či promyšlených modifikacích) by mohlo být vidět, že:

 

·        udělat SW bedničku (monitor), která dovede v aplikaci běžící na symetrickém  multiprocesoru "rychle sčítat", dá dost práce,

·        čili nemá cenu něco takového dělat pro "jednorázové použití",

·        a když už se dělá "reusable" monitor" (moderní termín je "SW komponenta"), stojí za to se zamyslet a udělat ho co nejuniverzálnější (např. ve stylu Adovských generic package).