Paralelní programování Synchronizační vzory – bariéra
Synchronizační vzory – mutex Mach Šebestová a1 count = count + 1 b1 count = count + 1 kolik semaforů? jaká počáteční hodnota?
Synchronizační vzory – mutex Mach Šebestová mutex(1) a1 mutex.acquire() b1 a2 count = count + 1 b2 a3 mutex.release() b3 kritická sekce acquire = wait, release = signal multiplex?
Synchronizační vzory – multiplex Mach Šebestová mutex(n) a1 mutex.acquire() b1 a2 count = count + 1 b2 a3 mutex.release() b3 semafor <> zámek token, místnost, povolenka, permanentka symetrické
Dežo v mutexu Zdroj obrázku: http://kecy.roumen.cz
Synchronizační vzory – bariéra symetrické rendezvous pro libovolný počet vláken všechna vlákna musí počkat až projdou bodem setkání po příchodu posledního vlákna mohou všichni pokračovat dál realizace n vláken poslední vlákno otevře bariéru
Synchronizační vzory – bariéra mutex.wait() count = count + 1 mutex.signal() if count == n barrier.signal() barrier.wait() kdy funguje? kdy nefunguje?
Bariéra – turniket mutex.wait() count = count + 1 mutex.signal() if count == n barrier.signal() barrier.wait()
Synchronizační vzory – bariéra praktické využití pracovní vlákna po dokončení práce se výsledky spojí rozdá se nová práce spouští se v cyklu potřebujeme bariéru, kterou lze znovu použít wait v kritické sekci (uvnitř mutexu) je nepoužitelný turniket – bod, kterým vlákna prochází po jednom, ale bez zdržení
Deadlock - drobná chybka mutex.wait() count = count + 1 if count == n barrier.signal() barrier.wait() barrier.signal() mutex.signal()
Bariéra – další (ne)řešení mutex.wait() count = count + 1 mutex.signal() if count == n turnstile.signal() turnstile.wait() count = count – 1 if count == 0 turnstile.wait(); Problém je, že procesy se mohou předbíhat (jeden proces může předběhnout všechny ostatní a vrátit se do bariéry znovu). Tj. chceme aby všechny procesy musely bariéru opustit a potom, aby se zase na bariéře sešly. problem?
Bariéra – další řešení počáteční hodnoty? mutex.wait() count = count + 1 if count == n turnstile2.wait() turnstile.signal() mutex.signal() turnstile.wait() /* process */ count = count – 1 if count == 0 turnstile.wait(); turnstile2.signal(); počáteční hodnoty?
Bariéra – další řešení mutex.wait() count = count + 1 if count == n turnstile.signal(n) mutex.signal() turnstile.wait() /* process */ count = count – 1 if count == 0 turnstile2.signal(n); turnstile2.wait() Pokud to semafor umožňuje, tak je možné propustit všechna vlákna z bariéry současně zasláním n signálů. Pak se dá řešení takto zjednodušit. turnstile2 = Semaphore(0)
Zdroj obrázku: http://antzinpantz.com/kns/archives/27242