IB109 Návrh a implementace paralelních systémů POSIX Threads - pokračování Win32 Threads Jiří Barnat Správa vláken • Vytváření, oddělování a spojování vláken • Funkce na nastavenia zjištění stavu vlákna Vzájemná vyloučení (mutexes) • Vytváření, ničení, zamykania odemykání mutexů 9 Funkce na nastavenia zjištění atributů spojených s mutexy Podmínkové/podmíněné proměnné (conditional variable) • Slouží pro komunikaci/synchronizaci vláken o Funkce na vytváření, ničení, "čekání na" a "signalizování při" specifické hodnotě podmínkové proměnné o Funkce na nastavenia zjištění atributů proměnných IB109 Návrh a implementace paralelních systémů: POSIX Threads - pokračování, Win32 Threads str. 2/46 Vzájemné vyloučení Motivace • Vícero vláken provádí následující kód if (my.cost < best_cost) best_cost = my.cost; 9 Nedeterministický výsledek pro 2 vlákna a hodnoty: best_cost==100, my_cost@l==50, my_cost@2==75 Řešení • Umístění kódu do kritické sekce • pthreadjiiutex_t Inicializace mutexu int pthread_mutex_init ( pthreadjiiutex_t *mutex_lock, pthreadjnutexattr_t *attribute) Parametr attribute specifikuje vlastnosti zámku • NULL znamená výchozí (přednastavené) nastavení IB109 Návrh a implementace paralelních systémů: POSIX Threads - pokračování, Win32 Threads str. 3/46 Vzájemné vyloučení int pthreadjnutex_lock (pthreadjnutex_t *mutex_lock) • Volání této funkce zamyká mutex.lock • Volání je blokující, dokud se nepodaří mutex zamknout • Zamknout mutex se podaří pouze jednou jednomu vláknu • Vlákno, kterému se podaří mutex zamknout je v kritické sekci • Při opouštění kritické sekce, je vlákno " povinné" mutex odemknout • Teprve po odemknutí je možné mutex znovu zamknout o Kód provedený v rámci kritické sekce je po odemčení mutexu globálně viditelný (paměťová bariéra) int pthreadjnutex_unlock (pthread_mutex_t *mutex_lock) 9 Odemyká mutex_lock IB109 Návrh a implementace paralelních systémů: POSIX Threads - pokračování, Win32 Threads str. 4/46 Vzájemné vyloučení Pozorování o Velké kritické sekce snižují výkon aplikace • Příliš času se tráví v blokujícím volání funkce pthreadjnutex_lock int pthreadjnutex_trylock (pthread_mutex_t *mutex_lock) 9 Pokusí se zamknout mutex • V případě úspěchu vrací 0 • V případě neúspěchu EBUSY • Smysluplné využití komplikuje návrh programu • Implementace bývá rychlejší než pthreadjnutex_lock (nemusí se manipulovat s frontami čekajících procesů) • Má smysl aktivně čekat opakovaným volání trylock IB109 Návrh a implementace paralelních systémů: POSIX Threads - pokračování, Win32 Threads str. 5/46 Vlastnosti (atributy) mutexů Normální mutex 9 Pouze jedno vlákno může jedenkrát zamknout mutex o Pokud se vlákno, které má zamčený mutex, pokusí znovu zamknout stejný mutex, dojde k uváznutí Rekurzivní mutex • Dovoluje jednomu vláknu zamknout mutex opakovaně • K mutexu je asociován čítač zamknutí o Nenulový čítač značí zamknutý mutex • Pro odemknutí je nutno zavolat unlock tolikrát, kolikrát bylo voláno lock Normální mutex s kontrolou chyby 9 Chová se jako normální mutex, akorát při pokusu o druhé zamknutí ohlásí chybu • Pomalejší, typicky používán dočasně po dobu vývoje aplikace, pak nahrazen normálním mutexem IB109 Návrh a implementace paralelních systémů: POSIX Threads - pokračování, Win32 Threads str. 6/46 int pthread_mutexattr_settype_np ( ptrheadjnutexattr_t *attribute int type) • Nastavení typu mutexu • Typ určen hodnotou proměnné type a Hodnota type může být • PTHREAD_MUTEX_NORMAL_NP • PTHREAD_MUTEX_RECURSIVE_NP • PTHREAD_MUTEX_ERRORCHECK_NP IB109 Návrh a implementace paralelních systémů: POSIX Threads - pokračování, Win32 Threa Podmínkové proměnné Motivace • Často na jednu kritickou sekci čeká vícero vláken • Aktivní čekání - permanentní zátěž CPU • Uspávání s timeoutem - netriviální režie, omezená frekvence dotazování se na možnost vstupu do kritické sekce Řešení 9 Uspání vlákna, pokud vlákno musí čekat • Vzbuzení vlákna v okamžiku, kdy je možné pokračovat Realizace v POSIX Threads • Mechanismus označovaný jako Podmínkové proměnné Podmínková proměnná vyžaduje použití mutexu 9 Po získání mutexu se vlákno může dočasně vzdát tohoto mutexu a uspat se (v rámci dané podmínkové proměnné) • Probuzení musí být explicitně signalizováno jiným vláknem IB109 Návrh a implementace paralelních systémů: POSIX Threads - pokračování, Win32 Threads str. 8/46 Podmínkové proměnné int pthread_cond_init ( ptrhead_cond_t *cond, pthread_cond_condattr_t *attr) o Inicializuje podmínkovou proměnnou • Má-li attr hodnotu NULL, podmínková proměnná má výchozí chování int pthread_cond_destroy ( ptrhead_cond_t *cond) • Zničí nepoužívanou podmínkovou proměnnou a související datové struktury IB109 Návrh a implementace paralelních systémů: POSIX Threads - pokračování, Win32 Threads str. 9/46 Podmínkové proměnné int pthread_cond_wait ( ptrhead_cond_t *cond, pthread_mutex_t *mutex_lock) • Uvolní mutex mutex_lock a zablokuje vlákno ve spojení s podmínkovou proměnou cond • Po návratu vlákno opět vlastní mutex mutex_lock • Před použitím musí být mutex.lock inicializován a zamčen volajícím vláknem int pthread_cond_signal ( ptrhead_cond_t *cond) o Signalizuje probuzení jednoho z vláken, uspaných nad podmínkovou proměnou cond IB109 Návrh a implementace paralelních systémů: POSIX Threads - pokračování, Win32 Threads str. 10/46 Podmínkové proměnné int pthread_cond_broadcast ( ptrhead_cond_t *cond) • Signalizuje probuzení všem vláknům čekajících nad podmínkovou proměnnou cond int pthread_cond_timedwait ( ptrhead_cond_t *cond, pthread_mutex_t *mutex_lock, const struct timespec *abstime) • Vlákno buď vzbuzeno signálem, nebo vzbuzeno po uplynutí času specifikovaném v abstime 9 Při vzbuzení z důvodu uplynutí času, vrací chybu ETIMEDOUT, a neimplikuje znovu získání mutex_lock IB109 Návrh a implementace paralelních systémů: POSIX Threads - pokračování, Win32 Threads str. 11/46 Podmínkové proměnné - typické použití 12 pthread_cond_t is.empty; 13 pthread_mutex_t mutex; 432 pthread_mutex_lock(&mutex); 433 while ( size > 0 ) 434 pthread_cond_wait (&is_empty, femutex); • • • 456 pthread_mutex_unlock(&mutex); 715 [pthread_mutex_lock(&mutex);] • • • 721 size=0; 722 pthread_cond_signal(&is_empty); 723 [pthread_mutex_unlock(&mutex) ;] IB109 Návrh a implementace paralelních systémů: POSIX Threads - pokračování, Win32 Threads str. 12/46 Globální, přesto vláknu specifické proměnné Problém • Vzhledem k požadavkům vytváření reentrantních a thread-safe funkcí se programátorům zakazuje používat globální data. o Případné použití globálních proměnných musí být bezstavové a prováděno v kritické sekci. o Klade omezení na programátory. Řešení • Thread specific data (TSD) • Globální proměnné, které mohou mít pro každé vlákno jinou hodnotu. IB109 Návrh a implementace paralelních systémů: POSIX Threads - pokračování, Win32 Threads str. 13/46 Implementace TSD Standardní řešení • Pole indexované jednoznačným identifikátorem vlákna, o Vlákna musí mít rozumně velké identifikátory. • Snadný přístup k datům patřící jiným vláknům - potenciální riziko nekorektního kódu. Řešení POSIX standardu • Identifikátor (klíč) a asociovaná hodnota. 9 Identifikátor je globální, asociovaná hodnota lokální proměnná. Klíč - pthread_key_t. • Asociovaná hodnota - univerzální ukazatel, tj. void *. IB109 Návrh a implementace paralelních systémů: POSIX Threads - pokračování, Win32 Threads str. 14/46 int pthread_key_create ( ptrhead_key_t *key, void (*destructor)(void*)) • Vytvorí nový klíč (jedná se o globální proměnnou). • Hodnota asociovaného ukazatele je nastavena na NULL pro všechna vlákna. o Parametr destructor - funkce, která bude nad asociovanou hodnotou vlákna volána v okamžiku ukončení vlákna, pokud bude asociovaná hodnota nenulový ukazatel. • Parametr destructor je nepovinný, lze nahradit NULL. IB109 Návrh a implementace paralelních systémů: POSIX Threads - pokračování, Win32 Threads Zničení klíče a asociovaných ukazatelů • int pthread_key_delete (ptrhead_key_t key) • Nevolá žádné destructor funkce. 9 Programátor je zodpovědný za dealokaci objektů před zničením klíče. Funkce na získání a nastavení hodnoty asociovaného ukazatele • void * pthread_getspecif ic (ptrhead_key_t key) • int pthread.set specif ic ( ptrhead_key_t key, const void *value) IB109 Návrh a implementace paralelních systémů: POSIX Threads - pokračování, Win32 Threads ptrheacLt pthreacLself () • Vrací unikátní systémový identifikátor vlákna int pth.read_equ.al (pthreacLt threadl, pthread_t thread2) • Vrací nenula při identitě vláken threadl a thread2 pthread_once_t once.control = PTHREAD_ONCE_INIT; int pthread_once(pthread_once_t *once_control, void (*init_routine) (void)); 9 První volání této funkce z jakéhokoliv vlákna způsobí provedení kódu init_routine. Další volání nemají žádný efekt. IB109 Návrh a implementace paralelních systémů: POSIX Threads - pokračování, Win32 Threads str. 17/46 Další funkce v POSIX Threads Plánování (scheduling) vláken • Není definováno, většinou je výchozí politika dostačující. o POSIX Threads poskytují funkce na definici vlastní politiky a priorit vláken. • Není požadována implementace této části API. Správa priorit mutexů Sdílení podmínkových proměnných mezi procesy Vlákna a obsluha POSIX signálů IB109 Návrh a implementace paralelních systémů: POSIX Threads - pokračování, Win32 Threads str. 18/46 Typické konstrukce IB109 Návrh a implementace paralelních systémů: POSIX Threads - pokračování, Win32 Threads str. 19/46 Čtenáři a písaři - WRRM Mapa Specifikace problému • Vlákna aplikace často čtou hodnotu, která je relativně méně často modifikována. (Write-Rarely-Read-Many) • Je žádoucí, aby čtení hodnoty mohlo probíhat souběžně. Možné problémy • Souběžný přístup dvou vláken-písařů, může vyústit v nekonzistentní data nebo mít nežádoucí vedlejší efekt, například memory leak. Souběžný přístup vlákna-písaře v okamžiku čtení hodnoty jiným vláknem-čtenářem může vyústit v čtení neplatných, nekonzistentních dat. IB109 Návrh a implementace paralelních systémů: POSIX Threads - pokračování, Win32 Threads str. 20/46 Řešení s použitím POSIX Threads ■v <* Ctení a modifikace dat bude probíhat v kritické sekci. • Přístup do kritické sekce bude řízen pomocí funkcí pthreacL*. Další požadavky • Vlákno-čtenář může vstoupit do kritické sekce, pokud v ní není nebo na ní nečeká žádné vlákno-písař. • Vlákno-čtenář může vstoupit do kritické sekce, pokud v ní jsou jiná vlákna-čtenáři. 9 Přístupy vláken-písařů jsou serializovány a mají přednost před přístupy vláken-čtenářů. IB109 Návrh a implementace paralelních systémů: POSIX Threads - pokračování, Win32 Threads str. 21/46 Čtenáři a písaři - Implementace Jednoduché řešení • Použít jeden pthread_mutex_t pro kritickou sekci, o Vylučuje souběžný přístup vláken-čtenářů. Lepší řešení • Implementujeme nový typ zámku - rwlock_t 9 Funkce pracující s novým zámkem • rwlock_rlock(rwlock_t *1) - vstup vlákna-čtenáře • rwlock_wlock(rwlock_t *1) - vstup vlákna-písaře • rwlock_unlock(rwlock_t *1) - opuštění libovolným vláknem • Funkce rwlock implementovány s pomocí POSIX Thread API IB109 Návrh a implementace paralelních systémů: POSIX Threads - pokračování, Win32 Threads str. 22/46 Čtenáři a písaři - Implementace rlock unl rlock sleep rlock KS unlock rlock unlock sleep wlock KS sleep wlock KS unlock IB109 Návrh a implementace paralelních systémů POSIX Threads - pokračování, Win32 Threads str. 23/46 Čtenáři a písaři - Implementace 1 typedef struct { 2 int readers; 3 int writer; 4 pthread_cond_t readers_proceed; 5 pthread_cond_t writer_proceed; 6 int pending.writers; 7 pthread_mutex_t lock; 8 } rwlock_t; 9 10 void rwlock_init (rwlock_t *1) { 11 l->readers = l->writer = l->pending_wr iters = 0; 12 pthread_mutex_init (&(l->lock) ,NULL) ; 13 pthread_cond_init (&(l->readers_proceed) ,NULL); 14 pthread_cond_init (&(l->writer_proceed) ,NULL) ; 15 } IB109 Návrh a implementace paralelních systémů: POSIX Threads - pokračování, Win32 Threads str. 24/46 Čtenáři a písaři - Implementace 16 17 void rwlock_rlock (rwlock_t *1) { 18 pthreadjnutex_lock(&(l->lock)); 19 while (l->pending_writers>0 || (l->writer>0)) { 20 pthread_cond_wait (&(l->readers_proceed), &(l->lock)); 21 } 22 l->readers++; 23 pthreadjnutex_unlock(&(l->lock)); 24 } 25 IB109 Návrh a implementace paralelních systémů: POSIX Threads - pokračování, Win32 Threads str. 25/46 Čtenáři a písaři - Implementace 26 27 void rwlock_wlock (rwlock_t *1) { 28 pthread_mutex_lock(&(l->lock)); 29 while (l->writer>0 || (l->readers>0)) { 30 l->pending_writers++; 31 pthread_cond_wait (&(l->writer_proceed), &(l->lock)); 32 l->pending_writers —; 33 } 34 l->writer++; 35 pthread_mutex_unlock(&(l->lock)); 36 } 37 IB109 Návrh a implementace paralelních systémů: POSIX Threads - pokračování, Win32 Threads str. 26/46 Čtenáři a písaři - Implementace 38 39 void rwlock_unlock (rwlock_t *1) { 40 pthreadjnutex_lock(&(l->lock)); 41 if (l->writer>0) 42 l->writer=0; 43 else if (l->readers>0) 44 l->readers—; 45 pthreadjnutex_unlock(&(l->lock)); 46 if ( l->readers == 0 && l->pending_writers >0) 47 pthread_cond_signal( &(l->writer_proceed) ); 48 else if (l->readers>0) 49 pthread_cond_broadcast ( &(l->readers_proceed) ) 50 } 51 IB109 Návrh a implementace paralelních systémů: POSIX Threads - pokračování, Win32 Threads str. 27/46 Čtenáři a písaři - Příklady použití Počítání minima 2122 2123 2124 2125 2126 2127 2128 2129 2130 2131 2132 rwlock_rlock(&rw_lock); if (myjmin < globaljnin) { rwlock_unlock(&rw_lock); rwlock_wlock(&rw_lock); if (my_min < global_min) global_min = my_min; } } rwlock_unlock(&rw_lock); { o Hašovací tabulky IB109 Návrh a implementace paralelních systémů: POSIX Threads - pokračování, Win32 Threads str. 28/46 Bariéry Specifikace problému « Synchronizační primitivům • Vláknu je dovoleno pokračovat po bariéře až když ostatní vlákna dosáhly bariéry. 9 Naivní implementace přes mutexy vyžaduje aktivní čekání (nemusí být vždy efektivní). Lepší řešení • Implementace bariéry s použitím podmínkové proměnné a počítadla. o Každé vlákno, které dosáhlo bariéry zvýší počítadlo. • Pokud není dosaženo počtu vláken, podmíněné čekání. IB109 Návrh a implementace paralelních systémů: POSIX Threads - pokračování, Win32 Threads str. 29/46 Bariéry - Implementace 1 typedef struct { 2 pthread_mutex_t count_lock; 3 pthread_cond_t ok_to_proceed; 4 int count; 5 } barrier.t; 6 7 void barrier_init (barrier_t *b) { 8 b->count = 0; 9 pthread_mutex_init (&(b->count_lock), NULL); 10 pthread_cond_init (&(b->ok_to_proceed), NULL); 11 } IB109 Návrh a implementace paralelních systémů: POSIX Threads - pokračování, Win32 Threads str. 30/46 Bariéry - Implementace 12 void barrier (barrier_t *b, int nr.threads) { 13 pthread_mutex_lock(&(b->count_lock)); 14 b->count ++; 15 if (b->count == nr_threads) { 16 b->count = 0; 17 pthread_cond_broadcast (& (b->ok_to_proceed)); 18 } 19 else 20 while (pthread_cond_wait (&(b->ok_to_proceed), 21 &(b->count_lock)) !=0); 22 pthread_mutex_unlock(&(b->count_lock)) ; 23 } IB109 Návrh a implementace paralelních systémů: POSIX Threads - pokračování, Win32 Threads str. 31/46 Bariéry - Efektivita implementace Problém 9 Po dosažení bariéry všemi vlákny, je mutex count_lock postupně zamčen pro všechny vlákna 9 Dolní odhad na dobu běhu bariéry je tedy 0(r?), kde n je počet vláken participujících na bariéře Možné řešení o Implementace bariéry metodou binárního půlení • Teoretický dolní odhad na bariéru je 0(n/p + log p), kde p je počet procesorů C" v y viceni • Implementujte bariéru využívající binárního půlení • Měřte dopad počtu participujících vláken na dobu trvání lineární a logaritmické bariéry na vámi zvoleném paralelním systému IB109 Návrh a implementace paralelních systémů: POSIX Threads - pokračování, Win32 Threads str. 32/46 Chyby, krom nezamykaného prístupu ke globální proměnné Typické chyby - situace 1 • Vlákno VI vytváří vlákno V2 e V2 požaduje data od VI o VI plní data až po vytvoření V2 o V2 použije neinicializovaná data Typické chyby - situace 2 • Vlákno VI vytváří vlákno V2 • VI předá V2 pointer na lokální data VI • V2 přistupuje k datům asynchronně a V2 použije data, která už neexistují (VI skončilo) Typické chyby - situace 3 • VI má vyšší prioritu než V2, čtou stejná data 9 Není garantováno, že VI přistupuje k datům před V2 • Pokud V2 má destruktivní čtení, VI použije neplatné data IB109 Návrh a implementace paralelních systémů: POSIX Threads - pokračování, Win32 Threads str. 33/46 Ladění programů s POSIX vlákny Valgrind • Simulace běhu programu. • Analýza jednoho běhu programu. Nástroje valgrindu • Memcheck - detekce nekonzistentního použití paměti. • Callgrind - jednoduchý profiler. • kcachegrind - vizualizace. • Helgrind - detekce nezamykaných přístupů ke sdíleným proměnným v POSIX Thread programech. IB109 Návrh a implementace paralelních systémů: POSIX Threads - pokračování, Win32 Threads str. 34/46 Rozšíření POSIX Threads - nepovinná dle standardu Barriéry o pthread_barrier_t • pthread_barrierattr_t • _init(...),-destroy(...), _wait(...) Read-Write zámky • pthread_rwlock_t o pthread_rwlockattr_t • _init(...), -destroy(...) • _rdlock(...), _wrlock(...),.unlock(...) • _tryrdlock(...) , _trywrlock(...) • _timedrdlock(...), _timedwrlock(...) IB109 Návrh a implementace paralelních systémů: POSIX Threads - pokračování, Win32 Threads str. 35/46 Další způsoby synchronizace IB109 Návrh a implementace paralelních systémů: POSIX Threads - pokračování, Win32 Threads str. 36/46 Synchronizace procesů Problém - jak synchronizovat procesy o Mutexy z POSIX Threads dle standardu slouží pouze pro synchronizaci vláken v rámci procesu. 9 Pro realizaci kritických sekcí v různých procesech je třeba jiných synchronizačních primitiv. • Podpora ze strany operačního systému. Semafory Čítače používané ke kontrole přístupů ke sdíleným zdrojům. 9 POSIX semafory (v rámci procesu) 9 System V semafory (mezi procesy) • Lze využít i pro synchronizaci vláken. IB109 Návrh a implementace paralelních systémů: POSIX Threads - pokračování, Win32 Threads str. 37/46 Semafory Semafor • Celočíselný nezáporný čítač jehož hodnota indikuje "obsazenost" sdíleného zdroje. • Nula - zdroj je využíván a není k dispozici. Nenula - zdroj není využíván, je k dispozici. • sem_init() - inicializuje čítač zadanou výchozí hodnotou • sem_wait() - sníží čítač, pokud může, a skončí, jinak blokuje • sem_post() - zvýší čítač o 1, případně vzbudí čekající vlákno Semafory vs. mutexy • Mutex smí odemknout pouze to vlákno, kterého jej zamklo. • Semafor může být spravován / manipulován různými vlákny. IB109 Návrh a implementace paralelních systémů: POSIX Threads - pokračování, Win32 Threads str. 38/46 y Monitor • Synchronizační primitivům vyššího programovacího jazyka. • Označení kódu, který může být souběžně prováděn nejvýše jedním vláknem. • JAVA - klíčové slovo synchronized Semafory, mutexy a monitory o Se semafory a mutexy je explicitně manipulováno programátorem. • Vzájemné vyloučení realizované monitorem je implicitní, tj. explicitní zamykání skrze explicitní primitiva doplní překladač. IB109 Návrh a implementace paralelních systémů: POSIX Threads - pokračování, Win32 Threads str. 39/46 Vlákna ve Win32 IB109 Návrh a implementace paralelních systémů: POSIX Threads - pokračování, Win32 Threads str. 40/46 Vlákna ve Win32 Vyšší programovací jazyk • C++11 • JAVA • ... POSIX Thread pro Windows • Knihovna mapující POSIX interface na nativní WIN32 rozhraní Nativní Win32 rozhraní • Přímá systémová volání (součást jádra OS) • Pouze rámcově podobná funkcionalita jako POSIX Threads • Na rozdíl od POSIX Threads nemá nepovinné části (tudíž neexistují různé implementace téhož). IB109 Návrh a implementace paralelních systémů: POSIX Threads - pokračování, Win32 Threads str. 41/46 Win32 vs. POSIX Threads - Funkce WIN 32 POSIX Threads Pouze jeden typ HANDLE Každý objekt má svůj vlastní typ (např. pthreacLt, pthread.jnutex_t, . . .) Jedna funkce pro jednu činnost, (např. WaitForSingleObject) Různé funkce pro manipulaci s různými objekty a jejich atributy. Typově jednodušší rozhraní (bez typové kontroly), čitelnost závislá na jménech proměnných. Typová kontrola parametrů funkcí, lepší čitelnost kódu. IB109 Návrh a implementace paralelních systémů: POSIX Threads - pokračování, Win32 Threads str. 42/46 Win32 vs. POSIX Threads - Synchronizace WIN 32 POSIX Threads Události (Events) Semafory Mutexy Kritické sekce Mutexy Podmínkové proměnné Semafory Signalizace pomocí událostí. Signalizace v rámci podmínkových proměnných. Jakmile je událost signalizována, zůstává v tomto stavu tak dlouho, dokud ji někdo voláním odpovídající funkce nepřepne do nesignalizovaného stavu. Signál zachycen čekajícím vláknem, pokud takové není, je signál zahozen. IB109 Návrh a implementace paralelních systémů: POSIX Threads - pokračování, Win32 Threads str. 43/46 Win32 vs. POSIX Threads - Základní mapování WIN 32 POSIX Threads CreateThread pthread_create pthread_attr_* ThreadExit pthread_exit WaitForSingleObj ect pthread_join pthread_attr_setdetachstate pthread_detach SetPriorityClass SetThreadClass Pouze nepřímo mapovatelné. setpriority sched_set scheduler sched_setparam pthread-setschedparam IB109 Návrh a implementace paralelních systémů: POSIX Threads - pokračování, Win32 Threads str. 44/46 Win32 vs. Linux/UNIX - Mapování synchronizace WIN32 Threads Linux threads Linux processes Mutex PThread Mutex System V semafor Kritická sekce PThread Mutex Semafor PThread podm. proměnné POSIX semafor System V semafor Událost PThread podm. proměnné POSIX semafor System V semafor IB109 Návrh a implementace paralelních systémů: POSIX Threads - pokračování, Win32 Threads str. 45/46 Win32 vs. UNIX - Pozorování Pozice vláken ve WIN32 • Silnější postavení než vlákna v Linuxu. • Synchronizační prostředky fungují i mezi procesy. • Vlákna ve vlákně (Processes-Threads-Fibers) Výhody jednoho typu • Jednou funkcí lze čekat na nekonkrétní vlákno. • Jednou funkcí lze čekat na vlákno a na mutex. IB109 Návrh a implementace paralelních systémů: POSIX Threads - pokračování, Win32 Threads str. 46/46