Käyttöjärjestelmä
Käyttöjärjestelmä on keskeinen tietokoneen ohjelmisto, joka mahdollistaa sovellusohjelmien toiminnan tietokoneessa. Sen tehtäviin kuuluu tietokoneen resurssien hallinta, laitteiston yksityiskohdista riippumattoman operointialustan tarjoaminen ja järjestelmäkutsujen toteuttaminen. Näiden lisäksi käyttöjärjestelmälle kuuluu huolehtiminen mm. tiedostojärjestelmästä, virtuaalimuistista, muistinhallinnasta, rinnakkaisuudesta, verkkoprotokollista, tietoturvasta ja lokeista. Myös erilaiset standardit, kuten POSIX tai sitä laajentava LSB, määrittelevät käyttöjärjestelmälle asetettavia vaatimuksia.
Ensimmäisissä tietokoneissa ei vielä ollut käyttöjärjestelmää. Ohjelmat kirjoitettiin reikäkorteille, paperi- tai magneettinauhoille, ja tietokoneelle annettiin tietty aika suorittaa ne. Jokainen suoritettava ohjelma piti ohjelmoida yksilöllisesti tietylle tietokoneelle, ja ohjelman tuli hallita kaikkia tietokoneen komponentteja ja oheislaitteita. Useiden ohjelmien samanaikainen käyttäminen oli hankalaa ja aikaa vievää, koska moniajoa ei ollut. Jos halusi suorittaa ohjelman uudelleen toisella syötteellä (input, lähtöarvo), piti ensin toinen ohjelma ladata koneeseen ja suorittaa se, ja sen jälkeen vaihtaa jälleen takaisin alkuperäiseen ohjelmaan, kelata se oikeaan kohtaan nauhaa tai levyä ja antaa itse toisen ohjelman syöte (input, lähtöarvo) kyseisen ohjelman lähteenä (output, lopputuloksena). Ohjelman suorittaminen toisenlaisella tietokoneella vaati ohjelman ohjauskäskyjen kirjoittamista uudelleen toisen tietokoneen laitekäskyjen mukaiseksi. Tämä hidasti ohjelmien käyttämistä muussa kuin samantyyppisessä tietokoneessa.
Laitteiston ja suoritettavan sovelluksen väliin sijoittuva käyttöjärjestelmä kehitettiin ratkaisemaan tällaisia perustavanlaatuisia käyttöongelmia. Käyttöjärjestelmään ohjelmoitiin käytettävien laitteistojen monimutkaiset ohjauskäskyt, ja nämä tarjottiin selkeinä järjestelmäkutsuina ohjelmistojen kehittäjille.
Ensimmäiset käyttöjärjestelmät suunniteltiin 1950- ja 1960-luvuilla. Ne laadittiin prosessien suoritusnopeutta ajatellen monoliittisiksi, yhtenä binääritiedostona toimiviksi ydintilassa. Ensimmäisten käyttöjärjestelmien muistirajoitus oli vain 32 tuhatta sanaa, mikä esti monimutkaisten käyttöjärjestelmien ohjelmoimisen. Niinpä käyttöjärjestelmät pysyivät helposti ohjelmoitavina. Teknisen kehityksen myötä käyttöjärjestelmien kokorajoitukset poistuivat. Tämä johti käyttöjärjestelmiin, jotka sisälsivät miljoonia rivejä koodia. Ohjelmakoodin monimutkaistumisen vuoksi harva ohjelmoija tunsi enää käyttöjärjestelmän toiminnan kokonaisuudessaan.
Käyttöjärjestelmän arkkitehtuuriin kuuluu ytimen ja sen laiteajureiden sijoittelu sekä erilaiset kirjastot. Käyttöjärjestelmän ytimen lisäksi käyttöjärjestelmään lasketaan usein sen mukana tulevat sovellukset, jotka tarvitaan käyttöjärjestelmän hallintaan kuten lisälaitteiden käsittelyyn, massamuistien alustukseen ja järjestelmän asetuksien muuttamiseen, joita ilman käyttäjäsovelluksien asentaminen voi olla vaikeaa tai mahdotonta.
Toiminnallisuuksia listaamalla ei voida yksiselitteisesti määritellä, mitä käyttöjärjestelmään kuuluu.
Tietokoneen komponenttien ja oheislaitteiden puolesta muille ohjelmistoille tarjotaan yhteneväinen rajapinta, esimerkiksi kiintolevyä käytetään yleensä tiedostojärjestelmän kautta ja verkkokorttia välittämättä tietoliikenneprotokollien yksityiskohdista. Tärkeimmät tehtävät laitteiston osalta suorittavat käyttöjärjestelmän laiteajurit, jotka toimivat ytimen ja laitteen välissä "tulkkeina".
Käyttöjärjestelmissä on tuki useille tiedostojärjestelmille, jolloin tallennuslaitteilla olevat tiedostot näytetään hakemistoina ja tiedostoina niiden merkityksen kannalta. Tiedostojärjestelmästä riippuen tiedostot merkitään eri tavoin osion kirjanpitoon erilaisten tarpeiden mukaisesti. Käyttöjärjestelmä hoitaa tallennuslaitteiden, kuten kiintolevyjen kirjoituksen ja lukemisen sekä se huolehtii myös tukemistaan erilaisista tiedostojen käyttöoikeuksista. Käyttöjärjestelmä hallitsee lähes aina useampia erilaisia tiedostojärjestelmiä, muutamasta useisiin kymmeniin. Tiedostojärjestelmän tuki voi olla myös käyttöjärjestelmään kuulumattoman ohjelmiston kuten FUSE:n (Filesystem in Userspace) avulla toteutettu, mutta sekin tarvitsee käyttöjärjestelmältä tuen toimiakseen. Tiedostojärjestelmä voidaan myös luoda yksittäiseen tiedostoon, joita käytetään erilaisissa salausjärjestelmissä.
Vanhimmissa koneissa ei ollut lainkaan muistinhallintajärjestelmää. Tämä tarkoitti sitä, että ohjelmat voitiin sijoittaa vain tiettyyn kohtaan keskusmuistia, ja ohjelma pystyi käsittelemään mitä muistinpaikkaa tahansa. Näistä aiheutuvien ongelmien ratkaisemiseksi muistinhallinnan päätehtäviksi ovatkin muodostuneet muistin suojaus ja samanlaisen osoiteavaruuden tarjoaminen kaikille prosesseille, ts. jokaisen prosessin osoiteavaruus alkaa nollasta riippumatta siitä, mihin kohtaan fyysistä muistia ohjelma on sijoitettu.
Muistinhallinnasta vastaa tyypillisesti muistinhallintayksikkö, joskin se voidaan integroida suorittimen kanssa yhteen. Käyttöjärjestelmä huolehtii muistinhallintayksikön ohjauksesta ja tarjoaa käyttöjärjestelmäpalvelut muistin varaamiseen ja vapauttamiseen. Muistinhallintayksikkö huolehtii laitteistotasolla siitä, että virheellinen muistiviittaus esimerkiksi käyttöjärjestelmän tai toisen prosessin alueelle aiheuttaa ohjelmavirhekeskeytyksen.
Prosessin muistia voidaan suorituksenkin aikana siirtää fyysiseltä muistialueelta toiselle, myös keskusmuistista massamuistilaitteelle ja takaisin (heittovaihto ja virtuaalimuisti). Käyttöjärjestelmä vapauttaa prosessin käyttämän muistin prosessin päättyessä.
Yksinkertaisin tapa varata prosessille muistialue on yhtenäinen pala keskusmuistia (). Tästä voi seurata tilanne, jossa muistia on kyllä tarpeeksi vapaana, mutta ei yhtenäisenä alueena, mikä aiheuttaa tarpeen tiivistää muistia. Ongelman pienentämiseksi voidaan muisti jakaa sivuihin, jolloin vain yksittäisen sivun täytyy olla yhtenäisenä muistissa, mutta peräkkäiset sivut voivat olla eri puolilla fyysistä muistia. Jos sivun koko ei ole vakio (ts. talletetaan sekä sivun alkuosoite että sen pituus), puhutaan myös muistin osioinnista (). Jos sivun koko on vakio, puhutaan sivutetusta muistista (). Muisti voidaan jakaa myös segmentteihin (), jolloin yhden segmentin pitää saada yhtenäinen alue keskusmuistista. Virtuaalimuisti toteutetaan lähes aina sivuttavan muistin päälle. Myös segmentoitu muisti voidaan jakaa sivuihin virtuaalimuistia varten.
Virtuaaliosoitejärjestelmissä ohjelman osoiteavaruus ja fyysinen muistiavaruus erotetaan toisistaan. Loogiset osoitteet ja fyysiset muistipaikat yhdistetään toisiinsa prosessikohtaisilla sivutauluilla () .
Virtuaalimuistijärjestelmässä on tämän lisäksi kyky tallettaa osia prosessin näennäisestä muistista massamuistilaitteelle. Mikäli ohjelma viittaa sellaiseen muistiosoitteeseen, jota ei ole keskusmuistissa, aiheutuu läsnäolokeskeytys (), jonka seurauksena käyttöjärjestelmä hakee halutun muistipaikan sisältävän muistilohkon massamuistilaitteelta keskusmuistiin. Tarvittaessa keskusmuistiin tehdään tilaa siirtämällä tietoja massamuistilaitteelle.
Ohjelman käynnistyessä käyttöjärjestelmä luo sille tarvittavan prosessin, muistiavaruuden ja tarvittavat tietorakenteet. Vastaavasti se vapauttaa nuo resurssit ohjelman lopetuksen yhteydessä. Käyttöjärjestelmä myös tarjoaa työkalut prosessien tarkkailuun, prosessien lopettamiseen ja prosessien väliseen kommunikointiin.
Moniajon ansiosta tietokoneessa voi samanaikaisesti olla ajossa useampia ohjelmia. Suoritin annetaan vuorotellen vähäksi aikaa eri prosessien (tai niiden säikeiden) käyttöön. Aika pidetään niin lyhyenä, että interaktiiviset ohjelmat näyttävät olevan ajossa koko ajan. Käyttöjärjestelmän "vuorottaja" pyrkii jakamaan suoritinaikaa tarkoituksenmukaisesti, huomioiden eri prosessien prioriteetin ja luonteen.
Käyttöjärjestelmä toteuttaa OSI-mallin 3. tason (verkkokerros) sekä 4. tason (kuljetuskerroksen) toteutukset toimiessaan muiden tietokoneiden/laitteiden kanssa verkossa ja tarjoaa nämä tasot sovellusohjelmien käyttöön. Ylemmät tasot toteutetaan muilla ohjelmistoilla kuten HTTP- tai FTP-palvelinohjelmistolla, P2P- tai Windows Live Messengerin asiakasohjelmilla. Käyttöjärjestelmän tehtävä on ainoastaan tarjota verkko- ja kuljetuskerros muille ohjelmille.
Monen käyttäjän käyttöjärjestelmissä käyttäjien oikeuksien rajoittaminen kuuluu käyttöjärjestelmän tehtäviin. Käyttäjän käynnistämien prosessien oikeudet riippuvat käyttäjän oikeuksista ja mahdollisesti muista seikoista. Jotkin käyttöjärjestelmät kuten MS-DOS oli suunniteltu yhdelle käyttäjälle, jolloin järjestelmään ei voinut olla kerralla kirjautuneina useampia käyttäjiä. Kyseinen käyttöjärjestelmä ei myöskään erotellut käyttäjäoikeuksia, vaan kaikki ohjelmat suoritettiin samoilla oikeuksilla.
Käyttöjärjestelmiä voidaan luokitella monin perustein:
On sellaisia, jotka sallivat ainoastaan yhden käyttäjän kerrallaan, kun taas monipuoliset voivat samanaikaisesti palvella useita käyttäjiä ja luoda illuusion siitä, että kukin heistä olisi yksin konetta käyttämässä. Nykyisin useimmat käyttöjärjestelmät mahdollistavat jonkinasteisen moniajon: käyttäjällä voi olla samanaikaisesti useampia kuin yksi prosessi (ohjelma) suoritettavana – vaikkapa tekstinkäsittelyohjelma ja mp3-tiedostosta musiikkia soittava ohjelma.
Moniajoa tukevat käyttöjärjestelmät voivat siis suorittaa useita prosesseja samanaikaisesti. Nykyiset käyttöjärjestelmät tukevat moniajoa lähes poikkeuksetta.
Jos käytettävissä on useita suorittimia tai yhdessä suorittimessa useita ytimiä, voidaan saavuttaa myös todellinen moniajo, jos käyttöjärjestelmä osaa hyödyntää niitä. Yhdellä suorittimella (suorittimella missä on yksi ydin) on mahdollista saavuttaa näennäinen moniajo suorittamalla prosesseja vuorotellen lyhyissä pätkissä. Moniajo on välttämätön ominaisuus monen käyttäjän interaktiivisissa järjestelmissä. 
Käyttöjärjestelmän kyky moniajoon mahdollistaa ohjelman skaalautumisen useaksi prosessiksi, jotka käyttöjärjestelmä suorittaa mahdollisesti suorittimilla tai suorittimen ytimillä, joilla on prosessointiaikaa tarjolla. Käyttöjärjestelmän täytyy osata kunnollinen moniprosessointi, jos sitä halutaan käyttää supertietokoneissa.
Käyttöjärjestelmiä voidaan jaotella myös niille saatavilla olevien käyttöliittymien perusteella. Komentopohjaisissa käyttöliittymissä käskyt kirjoitetaan näppäimistöllä komentotulkin tulkittaviksi, kun taas graafisissa käyttöliittymissä käytetään usein hiirellä ja näppäimistöllä ikkunoita, valikkoja, kuvakkeita ja muita graafisia elementtejä, jolloin käyttöliittymän toteuttavat ohjelmat välittävät tähän perustuvia käskyjä käyttöjärjestelmälle, joka välittää ne edelleen suoritettavilla ohjelmille.
Luokittelua monimutkaistaa se, että yhdelle käyttöjärjestelmälle voi olla tarjolla useampia – sekä merkkipohjaisia että graafisia – käyttöliittymiä, jotka voivat myös olla käytössä yhtä aikaa. Esimerkiksi vanhalle merkkipohjaiselle MS-DOS-käyttöjärjestelmälle tehtiin aikoinaan graafinen ikkunointiympäristö nimeltä Windows, johon myöhemmin Windows 95 -version myötä siirrettiin osa käyttöjärjestelmän toiminnoista. Vastaavasti alkujaan komentorivillä käytetty UNIX-käyttöjärjestelmä sai ikkunointijärjestelmä X Window Systemin, jonka avulla suoritetaan erilaisia graafisia käyttöliittymiä, kuten ikkunamanagereja sekä työpöytäympäristöjä, esimerkiksi Common Desktop Environment, KDE, GNOME, XFCE ja LXDE. Useimpia nykyisiä järjestelmiä voi ohjata myös pelkästään komentoriviltä, esimerkiksi Microsoftin Windowsia ja Applen OS X:ää. Unixeissa (mukaan luettuna Linux) komentorivin käyttö on yleistä tietynlaisissa tehtävissä, vaikka työpöytäsovellukset ovatkin graafisia.
Jonkinlainen käyttöliittymä on kuitenkin tarpeen käyttäjälle. Tämä on useimmiten komentotulkki tai graafinen käyttöliittymä, joita ei pidetä käyttöjärjestelmän osina, ellei niitä ole varta vasten ohjelmoitu käyttöjärjestelmään, vaan ne ovat useimmiten toimivia ohjelmistoja ja vaativat käyttöjärjestelmän toimiakseen. Käyttöliittymä voi myös koostua sovellusohjelmasta muun muassa sulautetuissa järjestelmissä tai järjestelmissä, joissa suoritetaan vain yhtä sovellusohjelmaa eikä tällöin ole tarvetta ohjelmistoille, jotka tarjoaisivat monimutkaisempia käyttöliittymiä.
Käyttöjärjestelmiä voidaan luokitella niiden käyttötarkoituksen mukaan.
Keskustietokone- ja palvelinkäyttöjärjestelmiä käytetään koneissa, joilla on monia samanaikaisia käyttäjiä tai joita käytetään palvelinten alustana. Usein nämä käyttöjärjestelmät voivat käyttää valtavaa määrää muistia, massamuistivälineitä, prosessoreita ja muita resursseja. Tavoitteena tällaisissa järjestelmissä on yleensä luotettavuuden ohella hyödyntää resursseja mahdollisimman täydellisesti ja suorittaa mahdollisimman suuri määrä tehtäviä aikayksikköä kohden.
Työpöytäkäyttöjärjestelmiä käytetään yksittäisissä henkilökohtaisissa tietokoneissa, joita käyttää yleensä kerralla yksi käyttäjä. Tärkeimpiä ominaisuuksia ovat käyttöliittymän helppokäyttöisyys ja hyvä vaste, yhteensopivuus heterogeenisen laitteiston kanssa sekä laajennettavuus.
Reaaliaikaiset käyttöjärjestelmät tähtäävät mahdollisimman pieniin ja ennakoitaviin viiveisiin käyttöjärjestelmän toiminnassa sekä äärimmäiseen toimintavarmuuteen. Useat sulautetut järjestelmät kuuluvat yleensä samaan kategoriaan. Sulautettuja ja reaaliaikaisia käyttöjärjestelmiä käytetään yleensä laitteissa, jotka on suunniteltu suorittamaan jokin tietty tehtävä mahdollisimman tehokkaasti. Tästä syystä myös energian ja laitteistoresurssien mahdollisimman säästeliäs ja tehokas käyttö ovat tärkeitä ominaisuuksia. Sulautettuja järjestelmiä hyödynnetään aina teollisuusroboteissa, DVD-soittimissa, mikroaaltouuneissa ja monissa muissa pienissä laitteissa. Kaikki sulautetut järjestelmät eivät kuitenkaan sisällä käyttöjärjestelmää, vaan ohjauksesta voi huolehtia pelkkä yksinkertainen firmware. Reaaliaikaisia käyttöjärjestelmiä ovat muun muassa: ChronOS, VxWorks, QNX, pSOS ja OS-9.
Käyttöjärjestelmät voidaan myös luokitella eri sukupolvien (0-4) mukaan, MS-DOSin kaltaisen "nollannen sukupolven" käyttöjärjestelmästä aina nykyaikaisiin neljännen sukupolven käyttöjärjestelmiin sekä tuleviin viidennen sukupolven käyttöjärjestelmiin, jotka toimivat osittain tai kokonaan verkossa.
"Käyttöjärjestelmät voidaan luokitella proseduuriorientoituneisiin tai prosessiorientoituneisiin. Prosessiorientoituneella käyttöjärjestelmällä on monia etuja proseduuriorientoituneihin käyttöjärjestelmiin verrattuna. Prosessirakenne antaa käyttöjärjestelmälle selkeän modulaarisen rakenteen, jossa yksittäinen palvelun toteutusta voidaan suhteellisen helposti muuttaa. Palveluprosessin oikeudet voidaan rajoittaa siten, että siinä olevan virheen vaikutukset minimoituvat. Myös käyttöjärjestelmäpalveluiden priorisointi yksinkertaistuu – proseduuriorientoituneessa käyttöjärjestelmässä prosessin prioriteettia joudutaan usein muuttamaan käyttöjärjestelmäpalvelun ajaksi. Myös laiteajureiden toteutus yksinkertaistuu. Pisimmälle vietyjä prosessiorientoituneita käyttöjärjestelmiä sanotaan rakenteensa takia myös mikroytimisiksi."
Yleisimmät käyttöjärjestelmät kuuluvat joko Windows-perheeseen tai johonkin lukuisista Unixin jälkeläisistä. Unix-perheessä on nähtävissä kaksi päähaaraa, joista toinen perustuu lähinnä BSD-unixiin (Berkeley Software Distribution), ja toinen Linux-ytimen pohjalta tehtyihin käyttöjärjestelmiin.
Työpöytäkoneissa yleisimpiä ovat Windows-perheen käyttöjärjestelmät, näistä tärkein on nykyisin Windows 10, joka perustuu Windows NT -käyttöjärjestelmään. Unix-pohjaisista Applen macOS on suosituin työpöytäkäytössä. Kyseinen käyttöjärjestelmä perustuu Darwiniin, joka taas on kehitetty BSD:n pohjalta.
Palvelinkoneissa noin kaksi kolmasosaa koneista käyttää jotain Unix-tyyppistä käyttöjärjestelmää ja näistä noin puolet Linuxia. Noin kolmasosa käyttää Windows-perheen käyttöjärjestelmää (2017).
Mobiililaitteissa Linux-pohjainen Android on kiistatta 
suosituin yli 70 prosentin osuudella (2017). Käytännössä sen lisäksi on käytössä vain Applen iOS.
Tablettilaitteissa suosituin on iOS noin kahden kolmasosan osuudella, Androidilla on noin kolmasosan osuus.
POSIX ei ole varsinainen käyttöjärjestelmä, vaan standardi, jonka kuvaa käyttöjärjestelmältä vaaditut ominaisuudet sovellusten siirrettävyyden takaamiseksi. Kaikki edellä mainitut käyttöjärjestelmät toteuttavat ko. standardin, mutta siirrettävyys toteutuu ainoastaan silloin, kun ohjelmiston tekijä on pitäytynyt vain POSIX-rajapinnan käytössä.