Moniajo

Moniajo () on tietokoneen käyttöjärjestelmän ominaisuus, joka mahdollistaa usean ohjelman ajamisen samanaikaisesti.
Jos tietokoneessa on vain yksi suoritin, moniajo toteutetaan jakamalla suorittimelle tehtäviä nopeasti vaihdellen (näennäisesti rinnakkain), kun taas monisuoritintietokoneessa tehtävät jaetaan usean suorittimen kesken ja voidaan suorittaa aidosti rinnakkaisesti (moniprosessointi).
Tehtävät voivat olla eri prosesseissa tai eri säikeissä: prosessi on suoritettava ohjelma ja säiettä kutsutaan toisinaan "kevyeksi prosessiksi", joka ei vaadi osoiteavaruuden vaihtoa.
Nykyaikaisempia moniajon toimintamalleja ovat "ennakoiva moniajo", "irrottava moniajo" ja "keskeyttävä moniajo" (engl. "pre-emptive"), jossa käyttöjärjestelmän osa tai prosessi nimeltä vuorontaja (”"skeduleri"”, engl. "scheduler") irrottaa ajossa olevan prosessin suorittimesta, valitsee uuden suoritettavan prosessin valmiustilassa olevien joukosta, antaa suorittimen sen hallintaan ja määrittelee sen saaman aikaviipaleen (). Näin vältetään yhteistyömoniajossa oleva ongelma, että yksi huonosti käyttäytyvä ohjelma voi varastaa koneen koko laskentatehon. Vuoronvaihto () tarkoittaa suorituksessa olevan ohjelman tilan säilömistä toisen ohjelman suorituksen ajaksi: tämä tarkoittaa suorittimen rekisterien arvojen säilömistä muistipinoon.
Suoritukseen annettava aikaviipale voi perustua useisiin eri tekijöihin kuten prosessin prioriteettiin sekä järjestelmän kokonaiskuormitukseen. Odottavalle säikeelle tai ohjelmalle voidaan antaa enemmän suoritusaikaa jotta se vapautuu tilanteestaan mahdollisimman nopeasti ja koska se voi luovuttaa () ajoaikansa mikäli odottaminen jatkuu.
Moniajo usein hyödyntää laitteiston keskeytyksiä vuoronvaihtoon, jolloin käyttöjärjestelmälle annetaan vuoro tarvittaessa tai ajoitetusti.
Vähemmän eksaktissa kielenkäytössä käytetään moniajo-termiä myös kuvaamaan sellaista käyttöliittymää, jossa käyttäjä voi vaihtaa "lennossa" usean sovelluksen välillä. Erityisesti termiä käytetään silloin, kun tällaista mahdollisuutta ei ole, ja todetaan virheellisesti, että moniajo puuttuu.
Historia.
Moniajon historia alkaa 1960-luvulta, jolloin osituskäyttöjärjestelmät kehitettiin yksittäisten, kalliiden suurtietokoneiden jakamiseksi.
Varhaiset moniajojärjestelmät käyttivät yhteistyömoniajoa, jonka jälkeen kehitettiin keskeyttävä moniajo. Yhteistyömoniajo riippui ohjelmien vapaaehtoisesta vuoron luovuttamisesta. Keskeyttävässä moniajossa laitteistokeskeytys herättää osan ohjelmakoodia, joka pakottaa vuoron vaihtamiseen.
Osituskäyttöön kehitettyjä järjestelmiä olivat muun muassa Compatible Time-Sharing System ja Dartmouth Time Sharing System, joita seurasivat käyttöjärjestelmät kuten Multics ja OS/360MFT.
Käyttöjärjestelmien vaatimukset vaihtelevat: sulautetuissa järjestelmissä ajetaan lähes aina reaaliaikaista käyttöjärjestelmää, jolla on tarkasti määritellyt kiinteät rajoitteet. Reaaliaikaisen käyttöjärjestelmän on vastattava määritellyissä rajoissa tai sen katsotaan epäonnistuneen toisin kuin osituskäyttöjärjestelmä, jossa nopea vasteaika on toivottavaa mutta ei pakollista, tai eräajokäyttöjärjestelmä jossa aikarajoja ei ole lainkaan.
NUMA-muistiarkkitehtuurissa tietokone voidaan käsittää koostuvan eri etäisyyksillä olevista moniprosessointia tukevista ”soluista”, jotka on kytketty toisiinsa: eri soluissa olevien suorittimien ja muistin välillä on tietty määrä kaistaa ja etäisyys, joka määrittää muistin käytön nopeuden.
Moniytimillisten suorittimien yleistyttyä moniprosessointia hyödyntävä vuoronnus on kiinnittänyt huomiota välimuistin paikallisuuden ja yhtenäisyyden käsittelyyn.
Muita vaikuttavia parametreja ovat energian tarve sekä lämpörajoitukset.
Irrottava/ennakoiva/keskeyttävä moniajo.
Useimmat "oikeaa" moniajoa tukevat järjestelmät käyttävät "irrottavaa", "ennakoivaa" tai "keskeyttävää" () moniajoa. Keskeyttävässä moniajossa laitteistokeskeytys herättää osan ohjelmakoodia, joka pakottaa vuoron vaihtamiseen.
Tämän tyyppistä monia käyttävät Unix-tyyppiset käyttöjärjestelmät, mukaan lukien BSD-versiot ja Linux. 
Linux tukee lisäksi ytimen itsensä keskeyttämistä. FreeBSD:ssä on rajattu ytimen keskeyttäminen mutta suunnitelmissa on tehdä siitä täysin keskeytettävä.
Mikrotietokoneissa tämän tyyppistä moniajoa ovat käyttäneet muun muassa AmigaOS Amiga-tietokoneissa (julkaistu 1985).
Myös TRIPOS on käyttänyt irrottavaa moniajoa. IBM siirtyi OS/2:n Warp-versiossa tukemaan ennakoivaa moniajoa.
Yhteistyömoniajo.
"Yhteistyömoniajo" () missä ohjelmat vapaaehtoisesti jakoivat suoritinaikaa toisille ohjelmille oli käytössä mm. RISC OS-käyttöjärjestelmässä ja Windows 95 -käyttöjärjestelmää edeltävät Windows-käyttöjärjestelmät.
OS X -käyttöjärjestelmää edeltävissä Mac OS -järjestelmissä oli myös yhteistyömoniajo. Microsoft siirtyi ennakoivaan moniajoon Windows NT:ssä ja Apple OS X:ssä (BSD-ydin).
OS/2 oli osittain ennakoivaa moniajoa tukeva (Warp-versiot), mutta osin rajattu yhteistyömoniajoon varhaisissa versioissa.
Moniohjelmointi.
Varhaisissa tietokonejärjestelmissä oli niin kutsuttua moniohjelmointikäsittelyä (), jossa toiselle ohjelmalle annetaan suoritusaikaa ennen ensimmäisen valmistumista.
Näissä tietokone suorittaa yhtä ohjelmaa kunnes ohjelma pysähtyy odottamaan esimerkiksi laite-IO:ta ja vaihtaa silloin suoritettavaa ohjelmaa.
Joissakin yhteyksissä moniohjelmoinnilla tarkoitetaan myös moniajoa ja eroa moderniin vastineeseen ei tehdä.
Reaaliaikainen.
Reaaliaikainen käyttöjärjestelmä perustuu takeeseen vasteajan noudattamisesta. Tämän tyyppinen moniajo voi erota teknisesti merkittävästikin, jotta aikarajattu toiminta () ei ylity missään tilanteessa.
Reaaliaikaisia käyttöjärjestelmiä ovat muun muassa QNX ja VxWorks.
Reaaliaikaiset järjestelmät voidaan jakaa kahteen: pehmeään (toivottu vasteaika) ja kovaan (vaadittu vasteaika). Pehmeässä aikarajan ohittaminen voi olla merkittävä menetys mutta kovassa järjestelmässä epäonnistuminen on katastrofaalinen. Kovan reaaliaikajärjestelmän vasteajat ovat tyypillisesti millisekunteja ja järjestelmän on vastattava ympäristön tapahtumiin. Kovan reaaliaikajärjestelmän vuoronnusta voidaan käyttää myös pehmeään reaaliaikajärjestelmään.
Kovan reaaliaikajärjestelmän vuoronnus voidaan jakaa dynaamiseen ja staattiseen: staattiseen ajoitukseen on tunnettava ennalta parametrit kuten suoritusajat ja aikarajat, mutta suorituksen aikainen kuormitus on pieni.
Kaksi tyypillistä tapaa toteuttaa vuoronnus reaaliaikajärjestelmässä ovat tapahtumapohjainen () ja aikajakava ():
Reaaliaikaisessa järjestelmässä vuoronnus voi perustua "kiinteän prioriteetin" ("fixed-priority") tai "varhaisin aikaraja ensin" ("earliest-deadline first") malliin. Moniprosessointia tukevat järjestelmät voivat jakaa mallit "globaaleihin", jossa tehtävät voivat käyttää kaikkia resursseja, sekä "osioituihin", joissa tehtävät asetetaan kiinteästi tietyille suorittimille.
Reaaliaikaisessa järjestelmässä luotetut sovellukset voivat kytkeä laitteistokeskeytykset pois päältä suojatun alueen käsittelyn ajaksi.
Reaaliaikaisiin käyttöjärjestelmiin on kehitetty useita protokollia prioteettien inversio-ongelman välttämiseksi. Näitä ovat muun muassa "Priority Inheritance Protocol" (PIP), "Priority Ceiling Protocol" (PCP) ja "Stack Resource Policy" (SRP).