Multiprocessing se dělá buď kvůli paralelnímu zpracování úlohy (jedna část řídí program, další části vykonávají nějakou činnost) nebo kvůli výkonu (čím víc CPU zapojíme do výpočtu, tím rychleji bude výsledek)
Pojmy
multitasking
multithreading
multiprocessing
Vlákna/threads
vlákno bývá označováno jako tzv. LWP - lightweight process (jednoduše to není heavy full proces)
vlákno se spouští uvnitř procesu a dokáže sdílet jeho systémové prostředky
Správu vláken provádí tzv. vláknová knihovna (thread library) na úrovni aplikačního procesu, JOS o jejich existenci neví
Přepojování mezi vlákny nepožaduje provádění funkcí jádra
Nepřepíná se ani kontext procesu ani režim procesoru
Aplikace má možnost zvolit si nejvhodnější strategii a algoritmus pro plánování vláken
výhody
Rychlé přepínání mezi vlákny (bez účasti JOS)
Lze použít i v OS, který vlákna nepodporuje; je nutná pouze vláknová knihovna
Rychlá tvorba a zánik vláken
Uživatelský proces má plnou kontrolu nad vlákny (např. může zadávat priority či volit plánovací algoritmus)
Nevýhody
systémová volání z jakéhokoliv vlákna blokuje činnost všech vláken. Systémové volání totiž zablokuje celý proces a předá řízení systému. Částečným řešením je nevolat funkce blokující systémová volání. Ono je to i logické, protože ty user space vlákna nikdy neběží paralelně (na více procesorech)
Jádro přiděluje procesor pouze procesům, takže dvě vlákna téhož procesu nemohou běžet současně, i když je k dispozici více procesorů … prý to jde nějak vynutit řikal frebauer, ale jestli to nebylo v kernel space :) nějakej set mask nebo co..
kernel space/level threads (KLT)
skutečný paralelismus, blokování jednoho vlákna neovliní vlákna další
Výhody:
Volání systému neblokuje ostatní vlákna téhož procesu
Jeden proces může využít více procesorů (skutečný paralelismus uvnitř jednoho procesu – každé vlákno běží na jiném procesoru)
Tvorba, rušení a přepínání mezi vlákny je levnější než mezi procesy
I moduly jádra mohou mít vícevláknový charakter
Nevýhody:
Systémová správa je režijně nákladnější než u čistě uživatelských vláken
Klasické plánování není spravedlivé: Dostává-li vlákno své kvantum, pak procesy s více vlákny dostávají více času
Praxe
Knihovna Pthreads poskytuje unifikované API:
Nepodporuje-li JOS vlákna, knihovna Pthreads bude pracovat čistě s ULT
Implementuje-li příslušné jádro KLT, pak knihovna Pthreads toho bude využívat
vytvoří zcela samostatný proces s kopií prostoru rodičovského procesu.
Uplaťnuje se přitom CoW (copy-on-write). Mechanismus CoW namapuje virtuální pamět potomka na fyzickou paměť rodiče. Až pří zápisu do paměti jakéhokoliv z procesů se přislušné modifikované stránky kopírují do nové stránky ve fyzické paměti
clone()
vytvoří vlákno, které dostane odkaz (pointer) na adresní prostor rodiče
umožňuje vláknu (task) sdílet adresní prostor s rodičem
samotná funkce clone se v programu většinou nepoužívá (využívají ji knihovny jako pthreads)
Poslední implementací je implementace NPTL (Native POSIX Thread Library). Tato implementace se opět vrací k mapování 1:1 (one-to-one, kernel vlakno = user space vlakno). Díky tomu odstraňuje nutnost použití dvou plánovačů. Implementace používá podobné techniky jako LinuxThreads (použití syscallu clone). Díky změnám v kernelu – např. přepracování syscallu clone, zavedení mapy alokovaných pid, O(1) plánovače, futexů a dalším – odstraňuje i výkonnostní problémy původní implementace LinuxThreads. Navíc je plně kompatibilní s normou POSIX. Tato implementace byla v době svého uvedení cca dvakrát výkonnější než NGPT. Uvedena byla přibližně ve stejné době jako NGPT – tj. v letech 2002/2003. Je součástí kernelu 2.6 a je plně integrována se současnou GNU C Library.
fork je programátorsky jednodušší
když se ukončí vlákno, někdo by měl vyzvednout návratovou hodnotu (funkce pthread_wait nebo tak)
vlákna sdílý paměť, otevřené soubory (fd), sockety, signály (bacha na obsluhu signálu, např používání sleep)