Multitasking
Multitasking (z angličtiny, multi = mnoho, task = úloha, používán ve víceúlohovém systému) označuje v informatice schopnost operačního systému provádět (přinejmenším zdánlivě) několik procesů současně. Jádro operačního systému velmi rychle střídá na procesoru běžící procesy (tzv. změna kontextu), takže uživatel počítače má dojem, že běží současně. Dnešní operační systémy jsou typicky víceúlohové – sem patří např. Microsoft Windows, Linux, macOS. Naopak DOS je příkladem jednoúlohového systému, na kterém vždy běží pouze jediný program a teprve po jeho ukončení je možné spustit jiný.
Za autora myšlenky multitaskingu bývá považován Edgar Frank Codd.
Motivace
Jednoúlohové systémy, jako například klasický MS DOS, umožňovaly spuštění nejvýše jednoho programu, což bylo pro uživatele počítače nepohodlné (musel nejprve rozpracovanou práci uložit, právě spuštěný program ukončit, spustit jiný program, zde provést požadovanou činnost a pak se vrátit zpět k dříve používanému programu a uložené práci). Na druhou stranu byl takový operační systém velmi jednoduchý a tudíž i nenáročný nejen na naprogramování, ale i na systémové zdroje počítačů, které v té době byly pomalé a měly málo operační paměti. Tyto systémy byly často tak jednoduché, že ani neposkytovaly ochranu samotnému systému (viz správa paměti), natož aby zajistily, že systém neztratí nad počítačem kontrolu (viz privilegovaný režim a preemptivní multitasking níže).
Protože byly počítače drahé, byla snaha o jejich vyšší využití (viz dějiny počítačů), které bylo možné zajistit tak, že ve chvíli, kdy počítač nebyl spuštěnou úlohou využíván (například při čekání na data z magnetické pásky), bylo možné spustit dočasně jinou úlohu. To vedlo ke vzniku víceúlohových operačních systémů, které využívaly multitasking. Avšak v tomto okamžiku bylo nutné zajistit ochranu samotného operačního systému, který zajišťoval přepínání běžících úloh, před samotnými úlohami, protože nesprávně naprogramovaná úloha mohla způsobit havárii i dalších (již spuštěných) úloh. Taková ochrana však vyžadovala podporu v procesorech, které musely poskytovat nástroje pro efektivní oddělení systému a běžící úlohy (tj. správa paměti), které znemožnilo právě běžící úloze měnit jinou část paměti, než jí byla přidělena. Aby celý systém nezhavaroval a nezpůsobil tak pád několika spuštěných úloh, musel procesor podporovat privilegovaný režim, který neumožnil úloze provést potenciálně nebezpečné strojové instrukce. Tím vznikly první skutečné operační systémy, které nikdy neztrácely nad počítačem kontrolu.
S rostoucím výkonem počítačů, jejich vysokou cenou i zvyšujícími se nároky uživatelů došlo k vývoji víceuživatelských operačních systémů, které s výhodou využily stávající víceúlohové systémy a přidaly navíc oddělení jednotlivých uživatelů a zavedení oprávnění v systému souborů.
Multiprogramování
Multiprogramování (anglicky multiprogramming) je technika vícenásobného zpracování, kdy se zdroje počítače dělí mezi více úloh. V počátcích bylo multiprogramování řešeno tak, že se úlohy vystřídaly v běhu v okamžiku, kdy jedna z nich čekala na pomalejší periferii, až dokončí vstupně-výstupní operaci (požadavek na tisk, čtení z pásky, disku a podobně). V dnešní době operační systém střídá úlohy v rychlém sledu, aby obsluha počítače mohla se všemi plynule pracovat. Multiprogramování tak v současné době využívá multitasking jako hlavní nástroj.
Programátor využívá multitasking zcela přirozeným způsobem, nemusí ho ve svém programu nijak řešit. Naopak může programovat tak, že předpokládá současný běh více procesů zároveň, využívá komunikaci mezi procesy, může problém vyřešit několika samostatnými programy, které jsou spuštěny současně a podobně.
Implementace
V počítači obvykle není k dispozici tolik procesorů, kolik úloh chceme spustit zároveň. Proto není možné zajistit, aby všechny spuštěné úlohy běžely současně. Místo toho je zajištěno, že se běžící úlohy na procesoru (resp. procesorech) počítače velmi rychle střídají a vytváří se tak zdání jejich současného běhu. Čas, po který je umožněno každé úloze běžet, se nazývá časové kvantum.
Na obrázku vpravo jsou znázorněny úlohy A, B a C, které se střídají v běhu na jednom procesoru, přičemž je naznačeno, že úloha může běžet kratší dobu, než je maximální časové kvantum.
Podle způsobu přidělování a odebírání časových kvant úlohám se rozlišují dva základní způsoby multitaskingu:
- kooperativní (nepreemptivní) multitasking
- preemptivní multitasking
Kooperativní (nepreemptivní) multitasking
Kooperativní multitasking vyžaduje aktivní spoluúčast běžících úloh. Každá úloha je povinna dostatečně často systémovým voláním předat řízení zpět operačnímu systému, který díky tomu může spustit jinou úlohu, která se po chvíli opět dobrovolně vzdá procesoru atd. Výhodou řešení je jednodušší implementace operačního systému. Podstatnou nevýhodou je skutečnost, že chybně naprogramovaná úloha, která nevrátí řízení zpět operačnímu systému, způsobí úplné zastavení systému i ostatních úloh.
Microsoft Windows, které nepoužívaly 32bitové jádro NT (tj. Windows 3.x, Windows 95, Windows 98), používaly nepreemptivní multitasking. Z marketingových důvodů byl však označován jako kooperativní multitasking s tím, že úloha, která byla na popředí (tj. měla aktivní okno), dostávala větší časová kvanta, než ostatní úlohy (které uživatel přímo neovládal, a proto mu to nevadilo, naopak systém vypadal jako výkonnější). Ve Windows 2.x (vydané v roce 1988) a novějších bylo možné samostatně spouštět více DOS aplikací, které běžely v preemptivním multitaskingu, ale vlastní Windows aplikace běžely v kooperativním multitaskingu, takže chybně naprogramovaná aplikace způsobila „zatuhnutí“ celého systému. Nepreemptivní multitasking používal též Mac OS (používaný před macOS) a RISC OS.
Preemptivní multitasking
V preemptivním multitaskingu o přidělování a odebírání procesoru jednotlivým úlohám plně rozhoduje operační systém. V pravidelných intervalech (typicky zhruba 100× až 1000× za sekundu) za pomoci časovače dojde k vyvolání přerušení aktuálně běžícího programu (procesu), vyhodnotí se aktuální situace (které úlohy žádají o přidělení procesoru, jejich priority atd.) a nechá běžet buď opět úlohu, kterou přerušil, nebo jinou úlohu, která má zájem o přidělení procesoru (to která úloha bude následně běžet, určuje prioritní fronta). I v preemptivním multitaskingu však může úloha dobrovolně požádat o přepnutí kontextu a vzdát se zbytku svého kvanta (úloha takzvaně „usne“ - proces přejde do stavu sleep nebo se zablokuje provedením pomalé vstupně-výstupní operace, jako je například čtení dat z pevného disku).
Preemptivní multitasking používají Windows 95 (jen pro 32bitové programy, zbytek běží nepreemptivně). Plně preemptivní je až řada Windows NT. Dále ho již od svého vzniku používá macOS, unixová jádra (včetně Linuxu) a další operační systémy.
Výhodou tohoto řešení je, že nedochází k „zatuhnutí“ počítače, neboť i v případě, že se úloha zacyklí, odebere operační systém pomocí časovače dané úloze řízení a přidělí procesor jiné úloze. Nevýhodou je složitější implementace operačního systému a nutnost hardwarové podpory v procesoru počítače (viz privilegovaný režim).
Atomické operace
U některých operací musí být zaručeno, že proběhnou celé, že jejich provádění nebude v polovině přerušeno např. přepnutím na jinou úlohu. Takové operace se označují jako atomické. Každá atomická operace musí proběhnout buď celá, nebo vůbec. Příkladem atomické operace je např. použití semaforu či jiného synchronizačního primitiva. Mezi zjištěním jeho stavu a následnou změnou nesmí být úloha přerušena, protože úloha, která by pak dostala řízení, by mohla stav semaforu změnit a došlo by k chybnému chování.
Příklad:
- Proces kontroluje, zda je na semaforu signál volno,
- Proces zjistí, že ano, proto se chystá nastavit stůj a vpustit vlak na trať.
- V tu chvíli ovšem dojde k přepnutí na jinou úlohu.
- Druhá úloha zkontroluje, že na semaforu je signál volno, nastaví stůj a z druhé strany vpustí vlak na trať.
- Dojde k přepnutí zpět na první úlohu.
- Ta dokončí nastavení na stůj a vpustí vlak na trať, čímž dojde ke kolizi.
U kooperativního multitaskingu je atomicita takových operací zaručena prostě tím, že se v jejím průběhu nevolají systémové funkce, které by umožnily přepnutí kontextu. Jelikož nikdy jindy k přepnutí dojít nemůže, je tím zaručena správná funkce. U preemptivního multitaskingu je naopak potřeba takovému nevhodnému přepnutí explicitně bránit - aplikace používají synchronizační primitiva implementovaná buď jako služby operačního systému, nebo s využitím hardwarové podpory. U skutečného multitaskingu, tzn. při práci na více procesorech, se atomicita operací zajišťuje pouze pomocí hardwarových prostředků: procesor poskytuje instrukce současně zjišťující a měnící stav paměti, které jsou nejen atomické z hlediska samotného procesoru, ale navíc vyvolají hardwarovou synchronizaci mezi procesory. V dřívějších systémech postačovalo „zamknout“ paměťovou sběrnici, tedy zabránit ostatním procesorům v přístupu k paměti. Moderní systémy vyžadují navíc zneplatnit části cache ostatních procesorů.
Multithreading
Multitasking vylepšil na úrovni operačního systému využití počítačů, protože v případě zablokování spuštěného programu (například vstupně-výstupní operací) byl procesor automaticky přidělen dalšímu (čekajícímu) procesu. Maximalizovalo se tak využití dostupného hardware. Programátoři začali záhy multitasking využívat též zcela vědomě tak, že v rámci řešení jednoho problému naprogramovali několik samostatných programů, které mohly díky multitaskingu spolupracovat. Typickým využitím multitaskingu je implementace síťových služeb, jako je webový server (například Apache HTTP Server), přeprava elektronické pošty (například Sendmail) a podobně, kde rodičovský proces naslouchá na síťovém rozhraní a příchozí požadavky předává ke zpracování svým potomkům. Jiným příkladem je paralelizace výpočtů (viz paralelní programování), kdy je možné využít výhody víceprocesorového systému.
Takové využití multitaskingu však přineslo výkonnostní problémy, které se projevovaly zvýšenou režií operačního systému na přepínání mezi jednotlivými úlohami (viz změna kontextu) a úzkým hrdlem v podobě nízké průchodnosti dat mezi jednotlivými procesy (viz meziprocesová komunikace). Při snaze o vyřešení těchto základních problémů byla do operačních systémů implementována podpora pro tak zvaná vlákna (tzv. odlehčené procesy, tato technika se nazývá multithreading). Hlavní vlastností vláken je sdílená paměť (běží ve stejném adresním prostoru), což je zároveň i jejich hlavní výhoda (vede ke snížení režie změny kontextu a snadnějšímu předávání dat mezi vlákny). Operační systém, který neobsahuje podporu vláken, může za pomoci nastavení sdílení paměti pracovat s běžnými procesy (avšak za cenu vyšší režie). Existuje též hardwarová podpora vláken.
Ochrana paměti
Při implementaci multitaskingu je důležité, aby operační systém podporoval ochranu paměti, díky které je možné zamezit úmyslné či neúmyslné změně v adresním prostoru různých současně spuštěných procesů nebo dokonce prostoru jádra operačního systému. Pokud se běžící proces pokusí přistupovat k paměti, která mu nepatří (nebyla mu přidělena modulem správy paměti v jádře operačního systému), je obvykle ještě před provedením této strojové instrukce jádrem operačního systému ukončen. Pro umožnění ochrany paměti je vyžadována podpora ze strany hardware (modulu správy paměti, který je součástí procesoru). Existují též operační systémy podporující multitasking, avšak bez ochrany paměti, které byly určeny pro procesory bez hardwarové podpory (procesory Intel a kompatibilní do příchodu Intel 80386).
Virtuální paměť
Virtuální paměť umožňuje nabízet běžícím procesům více operační paměti, než je fyzicky v počítači přítomno pomocí jejího rozšíření o místo na pevném disku. I když mechanismus virtuální paměti přímo s multitaskingem nesouvisí, jsou obě techniky u pokročilých operačních systémů typicky využívány společně.
Reference
V tomto článku byl použit překlad textu z článku Computer multitasking na anglické Wikipedii.