Ohjelmoinnin peruskurssien laaja oppimäärä

Samankaltaiset tiedostot
Ohjelmoinnin peruskurssien laaja oppimäärä

Concurrency - Rinnakkaisuus. Group: 9 Joni Laine Juho Vähätalo

Ohjelmoinnin perusteet Y Python

Luento 6. T Ohjelmoinnin jatkokurssi T1 & T Ohjelmoinnin jatkokurssi L1. Luennoitsija: Otto Seppälä

Transaktiot - kertausta

5. Luento: Rinnakkaisuus ja reaaliaika. Tommi Mikkonen,

Ohjelmoinnin perusteet Y Python

Rinnakkaisuus. parallel tietokoneissa rinnakkaisia laskentayksiköitä concurrent asioita tapahtuu yhtaikaa. TTY Ohjelmistotekniikka

Ohjelmoinnin peruskurssien laaja oppimäärä

Ohjelmoinnin peruskurssien laaja oppimäärä

Ohjelmoinnin perusteet Y Python

Käyttöjärjestelmät: poissulkeminen ja synkronointi

Ohjelmoinnin perusteet Y Python

Ohjelmoinnin peruskurssien laaja oppimäärä

Harjoitustyö: virtuaalikone

Chapel. TIE Ryhmä 91. Joonas Eloranta Lari Valtonen

Liite 1. Projektin tulokset (Semaforit Javassa) Jukka Hyvärinen Aleksanteri Aaltonen

Ohjelmoinnin peruskurssien laaja oppimäärä

4. Luento: Prosessit ja säikeets. Tommi Mikkonen,

Ohjelmoinnin perusteet Y Python

Graafisen käyttöliittymän ohjelmointi Syksy 2013

Ohjelmoinnin perusteet Y Python

Ohjelmoinnin peruskurssi Y1

Ohjelmoinnin perusteet Y Python

Ohjelmoinnin peruskurssien laaja oppimäärä

Pythonin Kertaus. Cse-a1130. Tietotekniikka Sovelluksissa. Versio 0.01b

Ohjelmoinnin peruskurssien laaja oppimäärä

Ohjelmoinnin perusteet Y Python

Ohjelmoinnin peruskurssien laaja oppimäärä

815338A Ohjelmointikielten periaatteet Harjoitus 5 Vastaukset

Ohjelmoinnin perusteet Y Python

11/20: Konepelti auki

Tähtitieteen käytännön menetelmiä Kevät 2009 Luento 5: Python

Ohjelmoinnin perusteet Y Python

Monitorit. Monitori Synkronointimenetelmiä Esimerkkejä. Andrews , Stallings 5.5

Monitorit. Tavoite. Monitori Synkronointimenetelmiä Esimerkkejä. Andrews , Stallings 5.5. Minimoi virhemahdollisuuksia

Ohjelmoinnin peruskurssi Y1

Ohjelmoinnin perusteet Y Python

815338A Ohjelmointikielten periaatteet Harjoitus 7 Vastaukset

Esimerkkiprojekti. Mallivastauksen löydät Wroxin www-sivuilta. Kenttä Tyyppi Max.pituus Rajoitukset/Kommentit

Ohjelmoinnin perusteet Y Python

Oppimistavoitteet kurssilla Rinnakkaisohjelmointi

Ohjelmoinnin peruskurssien laaja oppimäärä, kevät

Ohjelmoinnin perusteet Y Python

Ohjelmoinnin perusteet Y Python

Ohjelmoinnin peruskurssi Y1

Ohjelmoinnin peruskurssi Y1

Ohjelmoinnin perusteet Y Python

Rinnakkaisuuden hyväksikäyttö peleissä. Paula Kemppi

Tutoriaaliläsnäoloista

2 Konekieli, aliohjelmat, keskeytykset

Ohjelmoinnin peruskurssien laaja oppimäärä

815338A Ohjelmointikielten periaatteet

815338A Ohjelmointikielten periaatteet Harjoitus 6 Vastaukset

Ohjelmoinnin perusteet Y Python

Ohjelmoinnin perusteet Y Python

Ohjelmoinnin perusteet Y Python

Ohjelmoinnin peruskurssi Y1

Johdatus Ohjelmointiin

Rinnakkaistietokoneet luento S

812315A Ohjelmiston rakentaminen. Asynkronisuus

Ohjelmoinnin peruskurssi Y1

Ohjelmoinnin peruskurssien laaja oppimäärä

OSA I: Yhteisten muuttujien käyttö Prosessit samassa koneessa. Sisältöä. Poissulkeminen. Halutut ominaisuudet 2-1. Rinnakkaiset, atomiset operaatiot

Rinnakkaisohjelmointi, Syksy 2006

815338A Ohjelmointikielten periaatteet

Ohjelmoinnin perusteet Y Python

Sisällys. 11. Javan toistorakenteet. Laskurimuuttujat. Yleistä

1. Tarkastellaan seuraavaa stokastista Petri-verkkoa: p 2. p 1. lock write 1

Ohjelmoinnin perusteet Y Python

Ongelmakenttä. Rinnakkaisuuden tarve. Kommunikointiin tarvitaan. Ympäristö Suunnittelun yksinkertaistaminen Suorituskyky Luotettavuus

Ongelmakenttä. Yhteenvetoa. Ratkottava. Mekanismit. Lukkomuuttujat. Lukkomuuttujat, Spin Locks. Rinnakkaisuuden tarve. Kommunikointiin tarvitaan

Yhteenvetoa. Ongelmakenttä

Ohjelmoinnin perusteet Y Python

Ohjelmoinnin perusteet Y Python

Ohjelmoinnin peruskurssi Y1

Palvelut. Sulautetut järjestelmät Luku 2 Sivu 1 (??) Sulautetut käyttöjärjestelmät

Ohjelmoinnin perusteet Y Python

Luento 17: Perintä. self.points = 0 self.status = 'Student'

Ohjelmoinnin perusteet Y Python

Lohkot. if (ehto1) { if (ehto2) { lause 1;... lause n; } } else { lause 1;... lause m; } 16.3

Ohjelmoinnin perusteet Y Python

Tähtitieteen käytännön menetelmiä Kevät 2009 Luento 6: Python

Ohjelmoinnin peruskurssi Y1

Ohjelmoinnin perusteet Y Python

Ohjelmoinnin peruskurssien laaja oppimäärä

Rajapinnat ja olioiden välittäminen

Ohjelmoinnin perusteet Y Python

Samanaikaisuuden hallinta

Sisällys. 15. Lohkot. Lohkot. Lohkot

Intel Threading Building Blocks

Ohjelmoinnin peruskurssi Y1

Ohjelmoinnin perusteet Y Python

Ohjelmoinnin peruskurssi Y1

Sisällys. 12. Näppäimistöltä lukeminen. Yleistä. Yleistä

Javan semaforit. Joel Rybicki, Aleksi Nur mi, Jara Uitto. Helsingin yliopisto

Lohkot. if (ehto1) { if (ehto2) { lause 1;... lause n; } } else { lause 1;... lause m; } 15.3

Sisällys. 16. Lohkot. Lohkot. Lohkot

Ohjelmoinnin peruskurssi Y1

SEPA REFAKTOROINTI Antti Ahvenlampi, 57408L Erik Hakala, 57509T

Transkriptio:

Ohjelmoinnin peruskurssien laaja oppimäärä Luento 11: Rinnakkaisuus Riku Saikkonen (osa kalvoista on suoraan ei-laajan kurssin luennoista) 25. 4. 2012

Sisältö 1 Rinnakkaisuusmalleja: säie ja prosessi 2 Säikeet Pythonissa 3 Säikeiden synkronointi: lukot ja monitorit 4 Muuta säikeisiin liittyvää 5 Rinnakkaisuuden ja säiemallin ongelmia 6 Muita rinnakkaisuusmalleja

(ei-laajan kurssin kalvo: luento 8 sivu 3) Säie Prosessi Kaikissa nykyaikaisissa käyböjärjestelmissä on mahdollista suoribaa useita ohjelmia yhtä aikaa KäyBöjärjestelmä ajaa jokaista ohjelmaa omassa prosessissaan, jakaen prosessoriaikaa ohjelmille niin, ebä ohjelmat näybävät toimivan samanaikaises3 Säie Yhden prosessin sisällä myös yksibäinen ohjelma voi suoribaa eri toimintoja samanaikaisees3 käybämällä säikeitä (thread) Säikeet ovat prosesseihin verrabuna selkeäs3 kevyempiä

(ei-laajan kurssin kalvo: luento 8 sivu 4) Säie Sopivas3 käytebynä säikeillä saadaan paljon etuja Ohjelma voi käybää prosessoriaikaa mahdollisimman tehokkaas3 hyväkseen Ohjelma voi vastata kaybäjän toimiin nopeammin jne. Jokaisella säikeellä on oma suorituspino Paikallisia muubujia (suorituspinossa) ei jaeta Kaikki muu on yhteistä (keossa) Pythonissa säikeet eivät todellisuudessa toteuta rinnakkaisuuba. ValiteBavas3. Ks seuraava sivu.

Miten säikeitä ajetaan? yleensä käyttöjärjestelmä toteuttaa säikeet useampi säie voi olla yhtäaikaa käynnissä esim. saman koneen eri prosessoreissa yhdelläkin prosessorilla säikeitä ajetaan vuorotellen joskus (nykyään harvoin) kieli itse toteuttaa säikeet ajamalla niitä vuorotellen samassa ohjelmassa säikeen suoritus voi keskeytyä mistä tahansa kohdasta (ja siirtyä toiseen säikeeseen) melkein: yleensä järjestelmä takaa esim. että int-muuttujan kirjoitus on muiden säikeiden näkökulmasta tehty joko kokonaan tai ei vielä ollenkaan säikeiden välinen kommunikointi perustuu siis yhteisen muistin käyttämiseen (shared memory) ja käytännössä säikeiden synkronointiin esimerkiksi lukoilla (ali)prosesseissa taas yhteistä muistia ei yleensä ole

Sisältö 1 Rinnakkaisuusmalleja: säie ja prosessi 2 Säikeet Pythonissa 3 Säikeiden synkronointi: lukot ja monitorit 4 Muuta säikeisiin liittyvää 5 Rinnakkaisuuden ja säiemallin ongelmia 6 Muita rinnakkaisuusmalleja

(ei-laajan kurssin kalvo: luento 8 sivu 5) Global Interpreter Lock (GIL) Pythonissa tulkki suoribaa kerralla vain yhtä säiebä. I/O toiminnot ovat poikkeus tähän. Ei pysty hyödyntämään moniydinsuorirmien kapasiteera Itse asiassa jopa hidastaa ohjelman toimintaa Todellinen rinnakkaisuus on Pythonissa toteutebu mul3prosessing moduulissa aliprosesseina Säie antaan kuitenkin muita etuja, jotka ovat muissakin ohjelmoin3kielissä hyödynnebävissä (ja oikeas3 rinnakkaises3). Jos aihe kiinnostaa: hbp://www.dabeaz.com/python/understandinggil.pdf

(ei-laajan kurssin kalvo: luento 8 sivu 6) Moduuli threading Luokka Thread mahdollistaa säikeiden ohjaamisen start() käynnistää säikeen run() sisältää säikeen toiminnot join() odobaa säikeen kuolemaa getname() kertoo säikeen nimen is_alive() kertoo, onko säie elossa

(ei-laajan kurssin kalvo: luento 8 sivu 9) Säikeen luon3 ja käynnistys Kuinka säie luodaan? Uusi säie voidaan luodaan luomalla uusi Thread- olio ja kutsumalla sen start- metodia start käynnistää säikeen halutusta aloituskohdasta Ennen start()- metodin kutsua säie on pysähdyksissä Tämä aloituspiste voidaan antaa periybämällä uusi luokka luokasta Thread Suoritus alkaa periytetyn luokan metodista run() run()- metodia ei kutsuta suoraan vaan Thread tekee sen kun sitä vastaava säie käynnistetään start:illa Säikeen suoritus pääbyy kun run()- metodista poistutaan

(ei-laajan kurssin kalvo: luento 8 sivu 10) import time import threading class Tulostaja(threading.Thread): def init (self, tulostettava): super(tulostaja, self). init () self.viesti = tulostettava def run(self): for i in range(10): time.sleep(0.5) print self.viesti + str(i)

(ei-laajan kurssin kalvo: luento 8 sivu 11) def main(): saiea = Tulostaja('Kissa : ') saieb = Tulostaja('Nalle : ') saiea.start() saieb.start() for i in range(10): time.sleep(1) print 'Main' + str(i) if name ==' main ': main()

(ei-laajan kurssin kalvo: luento 8 sivu 12) Metodeista is_alive()/isalive() Tiedustelee, onko tutkibu säie vielä elossa join() OdoBaa, kunnes säie, jonka join- metodia kutsurin, kuolee Voidaan vaikka odobaa, ebä jonkin olennaisen tehtävän suoritus saadaan loppuun Voi olla kätevä ohjelman alasajossa Join ei siis lopeta säikeitä

Sisältö 1 Rinnakkaisuusmalleja: säie ja prosessi 2 Säikeet Pythonissa 3 Säikeiden synkronointi: lukot ja monitorit 4 Muuta säikeisiin liittyvää 5 Rinnakkaisuuden ja säiemallin ongelmia 6 Muita rinnakkaisuusmalleja

(ei-laajan kurssin kalvo: luento 8 sivu 14) Synkronoin3 Kun kaksi tai useampi säiebä haluaa käybää jotakin yhteistä resurssia (muubuja, 3edosto, ) yhtä aikaa, täytyy pitää huolta, ebä vain yksi säie kerrallaan käsibelee resurssia Jos kaksi säiebä avaa saman 3edoston ja kirjoibaa siihen, menevätkö rivit sekaisin? Toimintaa, joka takaa yksi kerrallaan periaabeen, kutsutaan synkronoinniksi Edellisen esimerkin tulostukset vaa3vat selväs3 synkronoin3a

(ei-laajan kurssin kalvo: luento 8 sivu 15) Lukot Yksinkertainen tapa varata resurssi yhdelle säikeelle kerralla on käybää lukkoa. (Lock) Luodaan lukko- olio ja välitetään se tarvibaville säikeille SuojaBavan toiminnon alussa pyydetään lukko Toiminnon valmistubua vapautetaan lukko

(ei-laajan kurssin kalvo: luento 8 sivu 16) def main(): lock = threading.lock() saiea = Tulostaja(lock, 'Kissa : ') saieb = Tulostaja(lock, 'Nalle : ') saiea.start() saieb.start() Välitetään lukot säikeille for i in range(10): time.sleep(1) lock.acquire() print 'Main' + str(i) lock.release() Suojataan pääohjelman tulostus

(ei-laajan kurssin kalvo: luento 8 sivu 17) class Tulostaja(threading.Thread): def init (self, lock, tulostettava): super(tulostaja, self). init () self.viesti = tulostettava self.lock = lock Lukko talteen def run(self): for i in range(10): time.sleep(0.5) self.lock.acquire() print self.viesti + str(i) self.lock.release() suojaus

Lukko-operaatiot (SICP 3.4.2) lukot (lock tai mutex) ovat usein matalimman abstraktiotason primitiivi säikeiden synkronointiin tyypillisesti lukolla on kaksi operaatiota: jokin säie voi varata (acquire) lukon ja myöhemmin vapauttaa (release) sen lukko takaa, että se on varattuna vain yhdellä säikeellä kerrallaan jos yrittää varata lukon, joka on jo varattu, normaalisti varausoperaatio jää odottamaan, että lukko vapautuu sisäisesti lukot on toteutettu joko käyttöjärjestelmän avulla tai yhteistä muistia sopivasti muokkaamalla semafori (semaphor) on lukko, joka voi olla varattuna n 1:llä säikeellä kerrallaan (raja n kerrotaan etukäteen)

Lukot ja monitorit toinen rinnakkaisuusabstraktio on nimeltään monitori (tai ehtomuuttuja, condition variable) varsinkin Javassä käytetään paljon tätä se käyttää lukkoja, mutta tarjoaa niille hieman abstraktimman rajapinnan: yksittäisten lukkojen varaus- ja vapautusoperaatioita ei näy koodissa lukot, semaforit ja monitorit ovat yleisimmät jaettuun muistiin perustuvat synkronointitavat oikeastaan abstraktiohierarkia ei ole näin selkeä: kaikki kolme voi periaatteessa toteuttaa toistensa avulla lisäksi on muunlaisia rinnakkaisuusmalleja, esimerkiksi viestinvälitykseen perustuvia (luennon loppupuolella)

(ei-laajan kurssin kalvo: luento 8 sivu 18) Synkronoin3 class Posti(object): def init (self): self.lahtevat_paketit = [] self.lock = threading.lock() def ota_paketti(self): #jotain koodia with self.lock: #käsittelee paketteja #loput metodista Mitä jos pakebeja ei ole otebavaksi? SäikeiBen väliseen synkronoin3in on omat keinonsa

(ei-laajan kurssin kalvo: luento 8 sivu 19) wait() ja no3fy() Mitä siis jos pakebeja ei ole otebavaksi? Silmukka, joka käy yribämässä, kunnes paker tulee Vie turhaan tehoa Ongelma ratkeaa metodeilla wait ja no3fy Kutsumalla lukko- olion metodia wait, säie siirtyy odobamaan Kun joku toinen säie kutsuu lukko- olion metodia no3fy, se heräbää yhden wait- jonon säikeen odobamaan pääsyä takaisin suoritukseen. (wait- kutsua seuraavalta riviltä) no3fyall() heräbää kaikki odobavat säikeet

(ei-laajan kurssin kalvo: luento 8 sivu 20) class Posti(object): POSTIN_KOKO = 15 def init (self): self.paketit = [] self.tuojat = threading.condition() self.viejat = threading.condition() def ota_paketti(self): while not self.paketit: with self.viejat: self.viejat.wait() poistettava = self.paketit.pop(0) with self.tuojat: self.tuojat.notifyall() return poistettava def tuo_paketti(self, p): while len(self.paketit) >= Posti.POSTIN_KOKO: with self.tuojat: self.tuojat.wait() self.paketit.append(p) with self.viejat: self.viejat.notifyall()

Sisältö 1 Rinnakkaisuusmalleja: säie ja prosessi 2 Säikeet Pythonissa 3 Säikeiden synkronointi: lukot ja monitorit 4 Muuta säikeisiin liittyvää 5 Rinnakkaisuuden ja säiemallin ongelmia 6 Muita rinnakkaisuusmalleja

(ei-laajan kurssin kalvo: luento 8 sivu 21) Timer Yksinkertaisin tapa saada jokin asia suoritebua 3etyn ajan kulubua on käybää Timer- luokkaa. SuoriBaa annetun funk3on/metodin annetun ajan kulubua SuoriBaa vain kerran, ei toista.

(ei-laajan kurssin kalvo: luento 8 sivu 22) import time import threading def tulosta(): print 'Tulostaa...' def main(): saiea = threading.timer(0.5, tulosta) saieb = threading.timer(0.7, tulosta) saiea.start() saieb.start() for i in range(10): time.sleep(1) print 'Main' + str(i) if name ==' main ': main()

(ei-laajan kurssin kalvo: luento 8 sivu 23) Toistava ajas3n Linkistä löytyy ajas3n, jolla on paremmat ominaisuudet Toistaa toiminnon annetun ajan välein Voi myös lopebaa toiston kertojen määrän täytybyä hbp://g- off.net/so^ware/a- python- repeatable- threading3mer- class

Säikeet ja GUI-ohjelmointi useimmat GUI-kirjastot on tehty niin, että GUI-kirjaston kutsuja saa tehdä vain yhdestä säikeestä helpottaa GUI-kirjaston tekemistä ja sen rajapinnan dokumentointia (muuten pitäisi ottaa kantaa siihen, mitä operaatioita saa tehdä yhtäaikaa ja mitä ei) mutta käyttöliittymässä asiat tapahtuvat yksi kerrallaan (hidas käyttöliittymäoperaatio pysäyttää kaiken muun) yleensä käyttöliittymäoperaatiot (esim. uuden dialog-ikkunan luonti) ovat kuitenkin lyhyitä tai osa niistä tehdään etukäteen ohjelman käynnistyessä käytännössä ohjelmissa on yleensä kaikki käyttöliittymään liittyvä koodi yhdessä säikeessä, joka lähettää pitkistä operaatioista laskentapyyntöjä muille säikeille

Sisältö 1 Rinnakkaisuusmalleja: säie ja prosessi 2 Säikeet Pythonissa 3 Säikeiden synkronointi: lukot ja monitorit 4 Muuta säikeisiin liittyvää 5 Rinnakkaisuuden ja säiemallin ongelmia 6 Muita rinnakkaisuusmalleja

Säikeiden ongelmia lukituksessa on helppo tehdä virheitä (esim. unohtaa varata lukko) vika saattaa esiintyä harvoin, jolloin se löytyy vasta myöhemmin rinnakkaisuusbugeja on yleensä vaikea toistaa löydetyn virhetilanteen tutkiminenkin voi olla vaikeaa lukkoja ei kannata olla kovin paljon lukon varaaminen vie aikaa vaikka se olisi vapaa (varaamisen pitää useimmiten onnistua, muuten rinnakkaisuudesta ei ole hyötyä) pitää löytää tasapaino tarkan ja epätarkan lukituksen välillä säikeitä ei kannata olla kovin paljon useimmat säietoteutukset eivät ole kovin tehokkaita, jos säikeitä on paljon (esim. useita kymmeniä tai satoja) yleensä ratkaisuna on ns. säieallas (thread pool): käynnistetään etukäteen esim. vakiomäärä säikeitä ja lähetetetään niille (yleensä lyhyitä) laskentapyyntöjä uuden säikeen käynnistämisen sijaan useimmissa ohjelmissa on yksi tai muutama säie, harvoin yli 10 monitorit ja semaforit eivät juurikaan auta näihin ongelmiin

Deadlock-ongelma (SICP 3.4.2) Kaksi rinnakkain ajettavaa säiettä varaa lukko a. varaa lukko b. vapauta b vapauta a varaa lukko b. varaa lukko a. vapauta a vapauta b mitä erikoista näitä säikeitä ajettaessa voi tapahtua?

Deadlock-ongelma (SICP 3.4.2) Kaksi rinnakkain ajettavaa säiettä varaa lukko a. varaa lukko b. vapauta b vapauta a varaa lukko b. varaa lukko a. vapauta a vapauta b mitä erikoista näitä säikeitä ajettaessa voi tapahtua? ohjelmat voivat jäädä ikuisesti odottamaan toisiaan: toinen haluaa toisen jo varaamaa lukkoa tämä tilanne on ns. lukkiuma (deadlock)

Deadlock-ongelman ratkaisuja (osin SICP 3.4.2) kaksi lukkiumaongelman ratkaisua: varataan lukot aina samassa järjestyksessä (estää lukkiuman syntymisen, mutta hankala toteuttaa, ellei tiedä etukäteen, mitä lukkoja tarvitsee) tunnistetaan lukkiuma ja puretaan se pyytämällä yhtä osallisista peruuttamaan miten lukkiuma tunnistetaan?

Deadlock-ongelman ratkaisuja (osin SICP 3.4.2) kaksi lukkiumaongelman ratkaisua: varataan lukot aina samassa järjestyksessä (estää lukkiuman syntymisen, mutta hankala toteuttaa, ellei tiedä etukäteen, mitä lukkoja tarvitsee) tunnistetaan lukkiuma ja puretaan se pyytämällä yhtä osallisista peruuttamaan miten lukkiuma tunnistetaan? esim. rakennetaan verkko siitä, mikä säie odottaa minkä säikeen varaamaa lukkoa tämän ns. odotusverkon sykli on lukkiuma vastaava ongelma on livelock: muuten sama, mutta ohjelmat eivät odota vaan tekevät jotain aktiivisesti silmukassa kunnes toinen valmistuu (eli ikuisesti) nämä ongelmat näkyvät jossain muodossa jokseenkin kaikissa rinnakkaisuuden muodoissa (aina kun varataan usempi jaettu resurssi)

Mitä rinnakkaisuusongelmille voi tehdä? käytännössä rinnakkaisuutta käytettäessä esimerkiksi: määritellään tarkkaan yhteisten resurssien käyttötapa (esim. mitä lukkoja pitää varata ennen kuin tiettyä muuttujaa käsitellään) pidetään rinnakkaisten ohjelman osien keskinäinen kommunikointi tavallistakin selkeämpänä (ja usein mahdollisimman vähäisenä) määritellään järjestys, jossa lukot tms. pitää varata joskus todistetaan rinnakkaisuuteen liittyviä ominaisuuksia rinnakkaisuutta käytetään paljon vähemmän kuin periaatteessa olisi mahdollista periaatteessa ongelmat liittyvät aina eri säikeiden väliseen kommunikointiin (yhteisten muuttujien käyttäminen on eräänlaista kommunikointia): esimerkiksi muille säikeille näkymättömistä välituloksista ei tarvitse huolehtia read-only-resurssit ovat helpompia: jos arvo ei muutu, sen rinnakkaisesta lukemisesta ei tarvitse huolehtia

Sisältö 1 Rinnakkaisuusmalleja: säie ja prosessi 2 Säikeet Pythonissa 3 Säikeiden synkronointi: lukot ja monitorit 4 Muuta säikeisiin liittyvää 5 Rinnakkaisuuden ja säiemallin ongelmia 6 Muita rinnakkaisuusmalleja

Muita tapoja tehdä rinnakkaisuutta edellä kuvattu säiemalli on yleisin tapa tehdä ohjelman sisäistä rinnakkaisuutta (toistaiseksi?) toinen yleinen malli on ajaa erillisiä prosesseja, jotka kommunikoivat esimerkiksi verkkoyhteyksillä tai tiedostoilla säiemallin vaihtoehdoksi on tehty monia muitakin rinnakkaisuusmalleja, esimerkiksi: yksittäisiä abstraktimpia operaatioita esim. taustalaskentaan transaktionaalinen muisti viestinvälitykseen perustuvia menetelmiä: säikeillä ei ole (tai ei näytä olevan) jaettua muistia, vaan ne kommunikoivat lähettämällä toisilleen viestejä lisäksi on hajautettu laskenta (distributed computing): rinnakkaisuutta niin, että eri säikeet pyörivät eri koneissa (yleensä perustuen viestinvälitykseen)

Abstraktimpia rinnakkaisuusprimitiivejä mm. Scala-kielessä on val x = future( lauseke ) siirtää lausekkeen arvon laskemisen taustalle toiseen säikeeseen jos x:n arvoa yritetään käyttää ennen kuin taustalaskenta on valmis, säie jää odottamaan sitä Scalan par( l1, l2 ) laskee kaksi lauseketta rinnakkain, odottaa niitä ja palauttaa parin, jossa on molempien arvot ja parmap on versio mapista, joka laskee (esim. taulukon) alkiot rinnakkain eri säikeissä näiden etu on, että lukituksia ei tarvitse miettiä itse (paitsi esim. lukkiuman mahdollisuutta) tällaisia abstraktimpia rinnakkaisuusprimitiivejä on moniin kieliin vasta juuri tullut tai tulossa (uudessa) Pythonissa ylläolevien tapaisia on moduulissa concurrent.futures

Transaktionaalinen muisti: toiminta transaktionaalinen muisti eli (software) transactional memory perustuu siihen, että rinnakkainen koodi jaetaan transaktioihin lukituksen sijaan transaktiota suoritetaan optimistisesti: luetaan arvoja ilman lukkoja ja tarkistetaan lopuksi että kaikki meni oikein keskeneräinen transaktio ollaan aina valmis perumaan (perutaan sen muistiin tekemät muutokset) muiden säikeiden kannalta transaktio on atominen: joko koko transaktion tekemä muutos näkyy muille säikeille, tai mitään osaa siitä ei näytä vielä olevan tehty ohjelmoijan pitää jakaa rinnakkainen koodi transaktioihin (niistä kohdista, joissa jokin muistiin tehty muutos on valmis näytettäväksi muille säikeille) ja säikeet pitää (yleensä) käynnistää itse mutta lukituskoodia tms. rinnakkaisuudenhallintaa ei tarvitse tehdä (vain transaktiorajat) myös transaktion peruutus tehdään automaattisesti

Transaktionaalinen muisti: toteuttaminen transaktionaalisesta muistista on kaksi perustoteutusta: software transactional memory: transaktiot toteutetaan ohjelmallisesti lukoilla ja/tai versioiduilla muistipaikoilla hardware transactional memory: toteutetaan osittain prosessorien sisällä eli raudassa (esim. ytimen sisäisen välimuistin avulla) yleensä rautatoteutuksen transaktiot ovat rajoittuneempia, ja usein sen taustalla on lisäksi ohjelmallinen toteutus puhtaasti ohjelmallinen toteutus lienee vielä yleisin transaktionaalisessa muistissa on kuitenkin käytännön rajoituksia transaktiot eivät käytännössä voi olla kovin isoja sisäkkäiset transaktiot ovat joskus ongelmallisia usein joitain operaatioita ei voi tehdä transaktion sisällä (esim. I/O vähintään puskuroidaan tehtäväksi transaktion lopuksi) transaktionaalinen muisti on melko uusi käsite eikä ole vielä kovin yleisesti käytössä (ehkä tulossa?) lisätietoja: ks. esim. Wikipediasta Software transactional memory

Actor-malli mm. Erlang- ja Scala-kielten actor-malli antaa helpomman tavan kommunikoida viestinvälityksellä säikeet kommunikoivat (vain) lähettämällä toisilleen viestiolioita, jotka voivat sisältää mitä tahansa dataa viesti voi olla esim. laskentapyyntö tai haku tietorakenteesta, ja yleensä paluuviestissä lähetetään vastaus vrt. että olion metodikutsu vastaa viestin lähettämistä sille (mutta actor-mallin viestit ovat usein hieman isompia kokonaisuuksia) yleensä kukin säie odottaa silmukassa uusia viestejä ja käsittelee ne tekemällä halutun operaation eroja tavalliseen viestinvälitykseen: lähetetään olioita (eikä tavu- tai merkkijonoja) vastaanotetun viestin käsittelevä koodi valitaan yleensä hahmonsovituksella (vrt. olion metodin valinta) toteutus voi jakaa actorit automaattisesti eri säikeisiin koska kaikki kommunikointi tapahtuu viesteillä, ohjelmoijan ei yleensä tarvitse ajatella lukkoja tai muuta synkronointia