Multitasking
Uit Wikipedia, de vrije encyclopedie
Multitasking is een methode om één processor schijnbaar meerdere taken (programma's of delen daarvan) tegelijkertijd te laten uitvoeren (zie ook multiprogrammeren). Het besturingssysteem wisselt zeer snel tussen de verschillende actieve programma's. Deze omschakelingen, context switches, kunnen geheel vrijwillig door het draaiende proces geïnitieerd worden of door een externe gebeurtenis zoals een hardware interrupt.
Inhoud |
[bewerk] Timesharing
In 1960-70 ondernamen onderzoekers de eerste pogingen om multitaskingsystemen te creëren. Dit heette toentertijd "timesharing" omdat het doel was om verschillende gebruikers tegelijkertijd gebruik te kunnen laten maken van een mainframe zodat diens bruikbaarheid toenam. De uitdrukking "timesharing" is in onbruik geraakt ten voordele van het meer algemene "multitasking".
[bewerk] Coöperatieve en preëmptieve multitasking
De allereerste multitasking systemen bestonden uit een reeks gerelateerde programma's die vrijwillig de processor aan elkaar vrijgaven. Deze aanpak, die uiteindelijk door verschillende besturingssystemen werd gebruikt, kennen we vandaag als coöperative multitasking. Hoewel het tegenwoordig zelden in grotere systemen gebruikt wordt, gebruikte Microsoft Windows het in de versies voor Windows 95 en gebruikte Mac OS het in de versies voorafgaand aan Mac OS X.
Coöperatieve multitasking kent verschillende tekortkomingen. Een dergelijk systeem vertrouwt er namelijk op, dat elk programma op het systeem regelmatig vrijwillig de processor vrijgeeft voor andere processen. Een slecht ontworpen programma of een programma dat "hangt", kan het systeem plat leggen. De ontwerpeisen voor een coöperatief multitaskingprogramma kunnen bijzonder zwaar zijn voor bepaalde toepassingen en kunnen uitmonden in een onregelmatig of inefficiënt gebruik van de systeembronnen.
Om dit probleem aan te pakken, gingen de meeste timesharingsystemen preëmptieve multitasking toepassen. Een systeem ontworpen met deze methode hoeft niet meer te vertrouwen op het vrijwillig vrijgeven van de processor, maar kan een hardware interrupt gebruiken om een draaiend programma te onderbreken waarna het besturingssysteem de controle over het systeem terugkrijgt. Op een later moment kan het besturingssysteem de controle weer teruggeven aan de taak die op precies dezelfde plek weer verdergaat als waar hij onderbroken werd. Taken hoeven dus niet expliciet tijd voor andere taken vrij te maken en programma's kunnen geschreven worden alsof ze continu toegang hebben tot de CPU.
Preëmptieve multitasking zorgt er dus voor dat een besturingssysteem makkelijker kan garanderen dat elke taak een deel van de processortijd toegewezen krijgt. Het maakt het ook mogelijk om snel te reageren op belangrijke externe gebeurtenissen zoals binnenkomende data die wellicht direct verwerkt moet worden door een taak.
[bewerk] I/O bound en cpu-bound
Taken kunnen gegroepeerd worden in twee categorieën: zij die wachten op invoer of uitvoer (I/O bound) en zij die de processor volledig gebruiken (CPU bound). In oudere systemen gebruikten taken polling en busywaiting terwijl ze wachtten op nieuwe data. Ze gebruikten daarbij de processor, zonder dat er nuttig werk werd verricht. Met de komst van interrupts en preëmptieve multitasking kunnen processen geblokkeerd worden zolang de gevraagde data niet beschikbaar is. Andere taken kunnen ondertussen wel gewoon gebruikmaken van de processor. Na aankomst van de data, maakt het besturingssysteem de taak weer actief zodat de data door het programma verwerkt kan worden.
[bewerk] Multiuser en multitasking
Multitasking was oorspronkelijk bedoeld om verschillende gebruikers een computer te laten delen. Het werd echter al snel duidelijk dat multitasking nuttig was ongeacht het aantal gebruikers. Besturingssystemen van mainframes tot personal computers ondersteunen het tegenwoordig. Multitasking maakt het mogelijk voor een enkele gebruiker om verschillende applicaties naast elkaar te draaien of om taken op de "achtergrond" te draaien en toch de computer te kunnen gebruiken.
Het ontwerpen van een algemeen realtimecomputersysteem wordt ook mogelijk gemaakt door multitasking. Een aantal verschillende externe gebeurtenissen moet bestuurd worden door een systeem met een enkele processor. In dergelijke systemen kent de interruptafhandeling prioriteiten toe aan de taken om er zo voor te zorgen dat de belangrijkste taken de meeste processortijd toegewezen krijgen.
Multitasking is over de jaren heen behoorlijk verfijnd. Moderne besturingssystemen bevatten mechanismen voor het toekennen van prioriteiten aan taken en ondersteunen ook taken met threads. Threads zijn onafhankelijke subtaken die het geheugen delen met andere threads. Er wordt onderscheid gemaakt tussen multitasking en multithreading.
Nieuwe hardwaremogelijkheden (zoals SMP, NUMA, multiprocessing) introduceren zowel nieuwe complexiteiten als nieuwe mogelijkheden.
[bewerk] Prioriteit
Voor verschillende taken die naast elkaar kunnen worden uitgevoerd kan men - afhankelijk van het beturingssysteem - de prioriteit aangeven. Bij meer ontwikkelde systemen als VMS en MVS kan de prioriteit van een taak tijdens de uitvoering veranderd worden, bij meer primitieve systemen kan deze prioriteit alleen bij het opstarten worden bepaald.
[bewerk] Voorbeeld coöperatieve multitasking
- Programma 1: bewerking A1, A2, A3
- Programma 2: B1, B2, B3
De scheduler van het besturingssysteem zou de taken als volgt kunnen inplannen:
- A1 B1 A2 B2 A3 B3
Maar het volgende is ook mogelijk:
- A1 A2 B1 B2 B3 A3
Omdat de programma's verschillende taken uitvoeren, hebben ze geen invloed op elkaar. Het wordt anders als een programma iets wil doen waar een ander programma al mee bezig is, bijvoorbeeld het schrijven naar een bestand. Als twee programma's naar hetzelfde bestand zouden schrijven, gaat een versie altijd verloren. Het is maar de vraag welke versie. Dit moet dus altijd worden voorkomen.
Programma's zijn in eerste instantie gemaakt alsof ze zonder te stoppen worden doorlopen. Dan kunnen er geen problemen optreden.
Voor beginnende programmeurs kan dit frustrerend zijn. Het volgende voorbeeld is een bekende beginnersfout omtrent multitasking:
- Balletje = groen
- Teken Balletje
- Wacht 10 seconden
- Balletje = rood
- Teken Balletje
De uitvoer zou zijn: Het programma lijkt 10 seconden niets te doen, daarna verschijnt een rood balletje. Het groene balletje lijkt niet getoond te worden.
Om dit probleem op te lossen moet het programma aangeven dat het even niets doet. Dit gebeurt met het commando ProcessMessages. De verbeterde code wordt nu:
- Balletje = groen
- Teken Balletje
- ProcessMessages
- Wacht 10 seconden
- Balletje = rood
- Teken Balletje
Nu verschijnt het groene balletje, na 10 seconden wordt het balletje rood. Tijdens (dus direct na) het commando ProcessMessages wordt niet alleen het balletje getekend. Het programma wordt in de 'wacht' gezet, en er wordt gekeken of er nog andere programma's in de wacht staan. Het programma wat het langste in de wacht stond wordt verder uitgevoerd tot het commando ProcessMessages weer wordt tegengekomen.
Een nadeel, aan de hand van het voorgaande voorbeeld:
- Het balletje is groen, en na 10 seconden wordt het rood. Maar in die 10 seconden blijft alles stilstaan. Je kan klikken en doen wat je wilt, het programma doet 10 seconden niets dan wachten. Dit is de oorzaak dat sommige programma's 'blijven hangen'. De oorzaak zit in een dergelijke programmeerfout.
Hoe moet het dan? In plaats van Wacht 10 seconden zou je kunnen zeggen:
- Wacht 5 seconden
- ProcessMessages
- Wacht 5 seconden
Resultaat: Het programma hangt gedurende 5 seconden. Het programma leeft even op, het scherm wordt ververst, en dan hangt het programma weer vijf seconden.