*Tämä artikkeli käsittelee tietotekniikan ja ohjelmoinnin käsitettä synkronoinnista. Tietoliikenteen ja signaalinkäsittelyn synkronointi on eri käsitteet.*
**Synkronointi** (engl. *synchronization*) tietokoneen ohjelmoinnissa tarkoittaa hallittua synkronointimekanismia rinnakkaisten ohjelmien välisen jaetun tiedon käsittelyyn.

Synkronointia tarvitaan, jotta kahden rinnakkain samanaikaisesti tapahtuvan muutoksen välillä ei synny kilpatilannetta (engl. *race condition*), jolloin ohjelmat voivat päivittää yhtä aikaa samaa muuttujaa tai tietorakennetta, mikä yleensä johtaa virheeseen. Tämän takia käyttöjärjestelmä tarjoaa mekanismeja resurssien hallittuun synkronointiin (engl. *synchronization*). 

Kilpatilanne voi syntyä myös yhden suorittimen järjestelmässä riippuen säikeiden ja prosessien vuoronnuksesta (*context switch*) sekä laitteistokeskeytyksien käsittelystä.

Nykyisin käytettävät *lukottomat* synkronointimekanismit välttävät suuren osan aiemmin tunnetuista ongelmista. Lukottomia menetelmiä ovat atomiset operaatiot sekä Read-Copy-Update (RCU) mekanismi.

Taustaa
-------

Rinnakkaisuuden käsittely on perustavanlaatuinen ongelma, jossa objektien tilan on pysyttävä aina eheänä ja pääsy objekteihin on synkronoitava. Rinnakkaisessa käsittelyssä ei toimita enää *sekventiaalisessa* ohjelmoinnissa ja sarjamuotoisista ohjelmointimenetelmistä ei ole apua. Menetelmiä synkronointiin on muun muassa lukituspohjainen synkronointi, joka tunnetaan myös *poissulkemisena*. Atomisuus (*linearisointi*) on tärkeä konsepti yhtäaikaisesti ja hajautetusti toimiville ohjelmille (erona *sarjamuotoisesta* eli *serialisoinnista*). Lukottomuudella tarkoitetaan menetelmiä, joissa *kriittistä aluetta* ei voi käyttää (*mutex-free*).

Synkronointimekanismit
----------------------

Kolme prosessia käyttämässä jaettua resurssia samanaikaisesti (kriittinen alue).
Prosessi käyttämässä jaettua resurssia sen ollessa saatavilla synkronointimekanismin avulla.
Synkronointimekanismit tai *synkronointiprimitiivit* ovat *sopimuspohjaisia* siten, että ohjelmakoodia tehtäessä on tunnistettava mitä muuttujia ei saa muokata lukituksen ollessa voimassa. Lukituksen käsittely tarvitaan sekä lukevalle että kirjoittavalle puolelle jotta molemmilla on käsitys milloin lukitus on voimassa.

Synkronointiin käytettäviä mekanismeja ovat *spinlock*, *barrier*, semaforit, (engl. *semaphore*) poissulkeminen (engl. *mutual exclusion*) ja kriittinen alue (engl. *critical section, critical region*), joilla varmistetaan, että vain yksi säie tai prosessi voi kerrallaan käsitellä yhteisiä muuttujia.

Eri mekanismeilla voi olla suorituskyvyn kannalta merkitystä lukituksen *haastamisen* (engl. *contention*) kannalta.

### Spinlock

*Spinlock* nimensä mukaisesti tarkastelee lukitusmuuttujaa kunnes se voi varata lukituksen (aktiivinen odotus). Tästä voi aiheutua *busy-wait* tilanne, mutta menetelmää yhä käytetään sen yksinkertaisuuden vuoksi. Ratkaisu riippuu arkkitehtuurikohtaisesta atomisesta *tarkista-ja-aseta* -toiminnosta. Tietokoneen suoritin voi tukea toimintoa ilman että laitteisto muuttaa tilaa kesken toiminnon.
*Sekventiaaliset lukitukset* (*Seqlocks*) ovat spinlockien variaatio, joka huomioi erikseen kirjoituksen ja lukituksen antaen kirjoitukselle korkeamman prioriteetin.
*Lippupohjaiselle* (*ticket*) ratkaisulle on vaihtoehtona kehitetty *jonopohjainen* (*queue*) suurissa NUMA-järjestelmissä käytettäväksi.

### Barrier

*Barrier* on esto, joka rajaa mm. kääntäjän tai suorittimen tekemän *uudelleenjärjestelyn* varmistaen että tietty ohjelmakoodi suoritetaan sitä ennen. Tähän voidaan liittää myös välimuistin tyhjentäminen keskusmuistiin (ks. välimuistin yhtenäisyys) ja muita toimintoja. Etenkin moniprosessointi voi vaatia mekanismia.

### Semafori

*Semafori* on kahden "suunnan" menettely, jossa lasketaan lukituksen ottaneet ja lukituksen vapauttaneet: kun lukituksen ottaneita on enemmän kuin lukituksen vapauttaneita muutoksia ei saa tehdä synkronoitavaan tietoon. Linuxin toteutus laskee sekä lukituksen ottaneet että odottajat.

Luku-kirjoitus-semaforit sallivat jaetun lukemisen, mutta vaativat yksityisen pääsyn kirjoittamista varten: menetelmä parantaa rinnakkaisuutta ja järjestelmän kokonaissuorituskykyä. Semaforipohjainen ratkaisu on suunnattu "luku-kirjoitus-ongelman" (engl. *reader-writer-problem*) ratkaisemiseen.

Tyypillinen semaforimekanismi ei ole sopiva reaaliaikaisten järjestelmien toteutukseen johtuen prioriteetti-inversion mahdollisuudesta.

Edsger Dijkstra mainitsee alankomaalaisen fyysikon C. S. Scholtenin osoittaneen semaforien soveltamista.

### Turnstile

*Turnstile* tai *kääntöportti* on Solaris-käyttöjärjestelmän toteuttama synkronointimenetelmä. Toteutus sisältää odotusjonot ja prioriteetin perintämekanismin.

### Fence

*Fence* (*aita*) on käytössä muun muassa grafiikkaprosessorin (GPU) ja suorittimen (CPU) välisessä synkronoinnissa.
Fence signaloidaan kun käsittely on valmis (GPU), jolla välin suoritin (CPU) voi tehdä työtä etukäteen.
Periaatteena on käsky, joka estää ohjelmointikielen kääntäjää ja laitteistoa järjestelemästä muistikäsittelyjä uudelleen: 1) fence valmistuu kun, sitä ennen annetut käsittelyt ovat valmiita; 2) fence on oltava valmis ennen kuin sen jälkeiset käsittelyt ovat näkyvissä muille prosessoreille.

### Poissulkeminen

*Poissulkeminen* on yleinen prosessien välillä käytetty synkronointi. Monet menetelmät toimivat vain säikeiden välillä nopeusedun vuoksi, mutta yleiset tietokoneresurssit kuten sarjaportti voivat vaatia varmistuksen että muiden prosessien säikeet eivät myöskään pääse käsittelemään samaa resurssia samaan aikaan. Linux toteuttaa *mutex* tyypin lisäksi *futex* poissulkemisen, joka on nopeampi mutta kernelin sisäisiin toimintoihin rajoitettu. Poissulkemisella voidaan tarkoittaa myös yleistä termiä akateemisissa ja teoreettisissa teoksissa.

Lukkiutumisen välttämiseen on kehitetty vaihtoehtona muun muassa *wait/wound mutex* (ww-mutex): tämä ratkaisee päinvastaisessa järjestyksessä varauksen "vahingoittamalla" myöhemmin tullutta vapauttamaan omansa, jotta ensin ehtinyt voi jatkaa. Perinteisesti vastakkaisia järjestyksiä on vain vältettävä. *Wait/wound*-mekanismia käytetään grafiikkaprosessorien kanssa (GPU), joissa on useita puskureita joiden järjestystä ei voi määrittää etukäteen: nämä puskurit voivat olla vuoroin GPU:n, laiteajurin, käyttäjäavaruuden tai mahdollisesti toisen ajurin käytössä (videokuvan kaappaus). Relaatiotietokantoja käsittelevässä kirjallisuudessa transaktioiden käsittelyssä vastaavasta lukituksesta käytetään nimeä *wait-die*.

Leslie Lamport on tutkinut ja todennut poissulkemisessa olevan useita ongelmia. Lamport myös esitti ensimmäisen hajautettuihin järjestelmiin sopivan ratkaisun poissulkemisongelmaan.
Lamportin mukaan hajautetuissa järjestelmissä ja moniprosessointia käyttävissä järjestelmissä on samanlaisia ongelmia, joissa tapahtumien järjestys ei ole ennakoitavissa.
Petersonin algoritmia sanotaan standardinomaiseksi alhaisen tason algoritmiksi kahden säikeen väliseen poissulkemiseen.

Poissulkeminen voi olla verrattain raskas ja hidas operaatio ja ohjelman sisäiseen synkronointiin käytetään tyypillisesti muita menetelmiä kuten kriittisiä alueita.

*Kiireinen odotus* (engl. *busy wait*) -tekniikoita käytetään paljon poissulkemiseen, mutta tyypilliset toteutukset vaativat paljon muistia sekä kytkentäverkon kilpatilanteita, jotka aiheuttavat pullonkauloja suorituskyvylle.

### Kriittinen alue

*Kriittinen alue* (engl. *Critical Section*) on ohjelmalohko, joka on suoritettava sen loppuun asti ennen luovuttamista toiselle suorittajalle.
Termiä käytetään synkronointiprimitiivin (*Critical Section*) lisäksi myös synkronoinnilla suojatusta ohjelmalohkosta.
Synkronointiprimitiivi *Critical Section* Windowsissa eroaa poissulkemisesta muun muassa siten, että se toimii vain saman prosessin säikeiden välillä eikä voida jakaa eri prosessien kesken.

Prosessin sisäisen suorituksen synkronointiin kriittinen alue voi olla tehokkaampi vaihtoehto kuin poissulkeva *mutex*.

### Atomisuus

*Atomisilla operaatioilla* voidaan tehdä ohjelmointikielen (ja laitteiston) tukemana automaattisesti suojattuja (synkronoituja) tai *lukottomia* muuttujia, joilla voidaan välttää kilpatilanteita.

Suorittimet sisältävät laitteistotasolla erilaisia *atomisia primitiivejä*, joita voidaan käyttää "rakennuspalikoina" muille synkronointimuunnelmille. Laitteiston tukemia primitiivejä ovat esimerkiksi: *test and set*, *compare and swap*, *fetch and increment* ja *load-link / store-conditional*.

Muun muassa C++11 lisää ohjelmointikieleen tuen atomisille operaatioille (ISO/IEC 14882:2011). Atomisilla operaatioilla voidaan toteuttaa korkeamman tason synkronointitoimintoja.

Atomiset operaatiot voivat parantaa suorituskykyä huomattavasti verrattuna perinteisiin synkronointimenetelmiin.

Microsoft on käyttänyt atomisista toiminnoista nimitystä *lomittuvat toiminnot* (engl. *interlocked operations*).

Atomisuutta käytetään synkronointiprimitiivien lisäksi myös muualla kuten tietokantojen ACID-periaatteessa sekä tiedostojärjestelmän toimintaperiaatteiden kuvauksissa, jotka ovat eri tason käsitteitä.

### ReaderWriterLock

*ReaderWriterLock* on Microsoftin synkronointiprivimitiivi, joka sallii useamman lukevan säikeen mutta vaatii kirjoittavan säikeen odottavan poissulkevaa lukitusta.

### Read-Copy-Update

*Read-Copy-Update* (RCU) mekanismi on Linuxissa käytetty skaalautuva mekanismi. RCU:n etu on äärimmäisen nopea lukeminen harvoin päivitettäville tiedoille.

RCU on immuuni *deadlock* tilanteelle ja se on lähtöisin Sequentin DYNIX/ptx ytimestä, jossa RCU:n käytöllä vähennettiin huomattavasti *deadlockin* välttämiseen tarkoitettua ohjelmakoodia. Mekanismia on käytetty myös IBM:n tutkimusalustassa K42.

Mekanismi käyttää *elävän* (luettavissa olevan) ja *kuolleen* (muokattavissa olevan) muuttujan periaatetta.

Koska menetelmä käyttää eri operaatioita *lukevalle* ja *kirjoittavalle* puolelle tähän viitataan myös *reader-writer locking* konseptina, mutta sillä korvataan Linuxissa käytettyä *read-write lock* mekanismia (rwlock).

RCU:sta on tehty esitys C++:n ISO-standardointiin liittyen.

Myös käyttäjäavaruudessa käytettävää muunnosta on kehitetty.

### Compare-and-Swap

Lukottomalle *Compare-and-Swap* -mekanismille perustuen on toteutettu moniprosessointia tukeva Synthesis-ydin Sony NEWS -työasemalle.

### Keskeytyskäsittely

Laitteistokeskeytyksien pysäyttäminen kriittisen alueen ajaksi on yksi reaaliaikajärjestelmien käyttämä menetelmä.
Keskeytyksien ja moniajon pysäyttäminen ei ole lukitus, mutta se voi olla alhaisen tason koodin käyttämä tiedon serialisointiin suoritinkohtaisesti.

### Lukottomat algoritmit

Lukoton algoritmi voi vaihtaa (esimerkiksi linkitetyn listan kanssa) käytössä olevan alkion toiseen kun se on valmis häiritsemättä olemassa olevaa käyttöä. Ohjelmointikielen kääntäjä on usein vapaa muuttamaan toimintojen järjestystä, joka voi aiheuttaa ongelmia. Lisäksi suorittimet voivat käyttää myös spekuloivaa suoritusta. Välimuistin yhtenäisyyden vuoksi suorittimet vaihtavat viestejä (QuickPath, HyperTransport) varmistaakseen järjestyksen. Assembly-tasolla ohjelmoija näkee operaatioita kuten *load-store*-käskyjä viestivälityksen sijaan.

Synkronointivirheet
-------------------

Rinnakkaiset ohjelmat voivat joutua myös odottamaan toisiaan jolloin säikeet estävät toisiaan (engl. *block*). 

Väärin tehty ohjelma voi lukkiutua (engl. *deadlock*). Lukkiutumistilanteessa prosessit odottavat tosiaan, eikä yksikään niistä pääse etenemään.

Nälkiintyminen tai nääntyminen (engl. *starvation*) on tilanne, jossa ainakin yksi säie jatkuvasti jää ilman riittävää suoritinaikaa, vaikka varsinaista lukkiutumista ei esiinnykään – järjestelmä siis ainakin osittain toimii kuten pitääkin.

*Livelock* on *deadlockin* ja nälkiintymisen kaltainen tilanne, jossa säikeet jatkavat toimintaansa mutta eivät pääse etenemään: säikeet eivät ole pysäytettyjä kuten deadlockissa. Käsitteen nimen esitti E. A. Ashcroft vuonna 1973 artikkelissaan *Proving Assertions about Parallel Program*.

*Priority inversion* tilanne on ongelmallinen vuoronnetuissa järjestelmissä, joissa korkean prioriteetin säie voi joutua odottamaan matalan prioriteetin säiettä vapauttamaan varatun resurssin, mutta matalan prioriteetin säie ei saa riittävästi ajoaikaa. Ongelman välttämiseksi Real-Time Linux tukee prioriteettien perintämekanismia.

Käytetystä synkronointimenetelmästä riippuen järjestelmä voi olla myös herkkä *busy-wait* tilanteelle, jossa suoritinaikaa käytetään paljon odotettavan lukituksen tilan tarkisteluun. Etenkin *spinlock* synkronointi voi aiheuttaa tämän tilanteen.

Synkronointituki
----------------

Itse alustakohtaisen tuen lisäksi eräissä ohjelmointikielissä on niiden standardikirjastossa toteutus alustakohtaiselle synkronointimekanismille, joka käyttää samaa rajapintaa eri alustoilla.

Esimerkiksi C++11 lisäsi `std::mutex` toteutuksen kielen standardikirjastoon. C11 lisäsi säikeistyksen tuen mukaan lukien synkronointituen.

Käyttö
------

Esimerkki synkronoinnin käyttötapauksesta:

```
Sync valuelock;
int myValue;

void write\_value(int scalarvalue)
{
 valuelock->lock();
 myValue = scalarvalue;
 valuelock->release();
}

int read\_value()
{
 int current\_value;

 valuelock->lock();
 current\_value = myValue;
 valuelock->release();

 return current\_value;
}

```

Huomaa, että tämä esimerkki olettaa synkronointiprimitiivin odottavan kunnes lukitus onnistuu ja voi pysäyttää säikeen suorituksen pitkäksi aikaa.

Esimerkki demonstroi miten lukittavan arvon käsittely on oltava sekä luku- että kirjoituspuolella *sopimuskäytännön* mukaisesti.

Katso myös
----------

* Aterioivat filosofit
* Producer–consumer problem (englanniksi)
* Readers–writers problem (englanniksi)
* Fork–join model (englanniksi)

Lähteet
-------

1. 1 2 3  Khushu, Sanjeev & Simmons, Johnathan: Scheduling and Synchronization in Embedded Real-Time Operating Systems (PDF) *cseweb.ucsd.edu*. Viitattu 20.2.2017.
2. 1 2 3 4  Jones, M. Tim: Anatomy of Linux synchronization methods IBM. Viitattu 21.2.2017.
3. ↑  Kernel Synchronization *cs.utexas.edu*. Viitattu 21.2.2017.
4. 1 2 3  Jonathan Corbet: Lockless algorithms for mere mortals *lwn.net*.  28.7.2020. Viitattu 1.11.2021. (englanniksi)
5. 1 2  Paolo Bonzini: An introduction to lockless algorithms *lwn.net*.  19.2.2021. Viitattu 1.11.2021. (englanniksi)
6. 1 2 3 4  Michel Raynal: *Concurrent Programming: Algorithms, Principles, and Foundations*, s. vi, 2, 112, 134. Springer, 2013. ISBN 978-3-642-32027-9. doi:10.1007/978-3-642-32027-9.  (englanniksi)
7. 1 2  Overview of Synchronization Primitives Microsoft. Viitattu 2.3.2017.
8. ↑  Schulzrinne, Henning: Synchronization primitives *cs.columbia.edu*. Viitattu 2.3.2017.
9. ↑  Synchronization primitives in the Linux kernel. *0xax.gitbooks.io*. Viitattu 2.3.2017.
10. ↑  Synchronization Primitives: Implementation and Examples *inst.eecs.berkeley.edu*. Viitattu 2.3.2017.
11. ↑  Lecture 4: Synchronization Primitives *cs.brown.edu*. Viitattu 2.3.2017.
12. ↑  18.5.7. Synchronization primitives *docs.python.org*. Viitattu 2.3.2017.
13. ↑  Choosing Between Synchronization Primitives Intel. Viitattu 2.3.2017.
14. ↑  Synchronization primitives *qnx.com*. Viitattu 2.3.2017.
15. ↑  Synchronization Primitives Apple. Viitattu 2.3.2017.
16. ↑  ARM® Synchronization Primitives Development Article ARM. Viitattu 2.3.2017.
17. ↑  Synchronization primitives IBM. Viitattu 2.3.2017.
18. ↑  Dillon, Matt: Multi-Processing Basics for a \*real\* multi-processing system. *groups.google.com*. Viitattu 2.3.2017.
19. 1 2  Blieberger, Johann & Burgstaller, Bernd & Scholz, Bernhard: Busy Wait Analysis *complang.tuwien.ac.at*. Viitattu 21.2.2017.
20. ↑  Chapter 6. Synchronization *helenos.org*. Viitattu 1.11.2021. (englanniksi)
21. ↑  Lecture 6: architectural support for synchronization *cs.cornell.edu*. Viitattu 1.11.2021. (englanniksi)
22. 1 2 3  Chapter 5. Kernel Synchronization *linux.linti.unlp.edu.ar*. Viitattu 21.2.2017.
23. ↑  Waiman Long: qspinlock: Introducing a 4-byte queue spinlock implementation *lwn.net*.  31.7.2013. Viitattu 1.11.2021. (englanniksi)
24. 1 2  McKenney, Paul E.: Memory Ordering in Modern Microprocessors *rdrop.com*. Viitattu 21.2.2017.
25. 1 2 3 4 5  Yang, Junfeng: W4118 Operating Systems *cs.columbia.edu*. Viitattu 21.2.2017.
26. ↑  McKenney, Paul E.: Memory Barriers: a Hardware View for Software Hackers *7.6.2010*. Viitattu 2.3.2017.
27. ↑  Read Write Semaphores *halolinux.us*.  1.3.2021. Viitattu 2.9.2021. (englanniksi)
28. ↑  H. Ballhausen: Fair Solution to the Reader-Writer-Problem with Semaphores only (PDF) *arxiv.org*. Viitattu 2.9.2021. (englanniksi)
29. ↑  Buttazzo, Giorgio C.: *Hard Real-Time Computing Systems*, s. 19. Third Edition. Springer, 2011. ISBN 978-1-4614-0675-4.
30. ↑  Edsger Dijkstra: 3.2 The Synchronizing Primitives (PDF) (sivu 28) *cs.utexas.edu*. Viitattu 1.11.2021. (englanniksi)
31. 1 2  Turnstiles and priority inheritance *sunsite.uakom.sk*. Viitattu 21.2.2017.
32. ↑  Understanding Vulkan Synchronization *khronos.org*. Viitattu 27.11.2021. (englanniksi)
33. ↑  Synchronization Framework *source.android.com*. Viitattu 27.11.2021. (englanniksi)
34. ↑  Asymmetric Memory Fences: Optimizing Both Performance and Implementability (PDF) *iacoma.cs.uiuc.edu*. Viitattu 27.11.2021. (englanniksi)
35. ↑  Generic Mutex Subsystem *kernel.org*. Viitattu 25.11.2021. (englanniksi)
36. 1 2 3  Jonathan Corbet: Wait/wound mutexes *lwn.net*.  1.5.2013. Viitattu 1.11.2021. (englanniksi)
37. 1 2  Wound/Wait Deadlock-Proof Mutex Design *kernel.org*. Viitattu 1.11.2021. (englanniksi)
38. 1 2  James H. Anderson: Lamport on Mutual Exclusion: 27 Years of Planting Seeds (PDF) *cs.unc.edu*. Viitattu 25.11.2021. (englanniksi)
39. ↑  Leslie Lamport: Time, Clocks, and the Ordering of Events in a Distributed System (PDF) *lamport.azurewebsites.net*.  heinäkuu 1978. Viitattu 25.11.2021. (englanniksi)
40. ↑  Peterson's Algorithm *cs.wcupa.edu*. Viitattu 8.6.2022. (englanniksi)
41. ↑  MSVC mutex is slower than you might expect *stoyannk.wordpress.com*. Viitattu 2.3.2017.
42. 1 2  Always Use a Lightweight Mutex *preshing.com*. Viitattu 2.3.2017.
43. ↑  John M. Mellor-Crummey & Michael L. Scott: Algorithms for scalable synchronization on shared-memory multiprocessors (PDF) *cs.rochester.edu*.  helmikuu 1991. Viitattu 25.11.2021. (englanniksi)
44. 1 2 3  Critical Section Objects Microsoft. Viitattu 2.3.2017.
45. ↑  Arpaci-Dusseau, Remzi H. & Arpaci-Dusseau, Andrea C.: Concurrency: An Introduction *pages.cs.wisc.edu*. Viitattu 2.3.2017.
46. ↑  William Stallings: *Operating System Internals and Design Principles*, s. 296. Seventh edition. Prentice Hall, 2012. ISBN 978-0-13-230998-1. (englanniksi)
47. ↑  Atomic Operations Intel. Viitattu 2.3.2017.
48. 1 2  Levi Ego: Memory Synchronization Techniques (PDF) *es.cs.uni-kl.de*. Viitattu 27.11.2021. (englanniksi)
49. ↑  
	* Stroustrup, Bjarne: *The C++ Programming Language, 4th ed.*. Addison-Wesley, 2015. ISBN 0-321-56384-0.
50. ↑  Comparison: Lockless programming with atomics in C++ 11 vs. mutex and RW-locks *arangodb.com*. Viitattu 9.2.2017.
51. ↑  Interlocked Operations Microsoft. Viitattu 2.3.2017.
52. ↑  Reader-Writer Locks Microsoft. Viitattu 2.3.2017.
53. 1 2 3  McKenney, Paul: What is RCU, Fundamentally? LWN. Viitattu 21.2.2017. (englanniksi)
54. ↑  McKenney, Paul E. & Boyd-Wickizer, Silas & Walpole, Jonathan: RCU Usage In the Linux Kernel: One Decade Later *eecg.toronto.edu*. Viitattu 2.3.2017.
55. ↑  Notes on Read-Copy Update *read.seas.harvard.edu*. Viitattu 2.3.2017.
56. ↑  McKenney, Paul E. & Sarma, Dipankar & Arcangeli, Andrea & Kleen, Andi & Krieger, Orran & Russell, Rusty: Read Copy Update *kernel.org*. Viitattu 2.3.2017.
57. ↑  McKenney, Paul: What is RCU? Part 2: Usage LWN. Viitattu 2.3.2017.
58. ↑  McKenney, Paul E.: Read-Copy Update (RCU) for C++ *open-std.org*. Viitattu 2.3.2017.
59. ↑  Userspace RCU Implementation *github.com*. Viitattu 14.4.2022. (englanniksi)
60. ↑  Massalin, Henry & Pu, Calton: A Lock-Free Multiprocessor OS Kernel (PDF) *web.cecs.pdx.edu*.  19.6.1991.  Arkistoitu 31.3.2020. Viitattu 26.10.2019. (englanniksi)
61. ↑  Marta Rybczyńska: Local locks in the kernel *lwn.net*.  11.8.2020. Viitattu 27.11.2021. (englanniksi)
62. ↑  Calibrating your fear of big bad optimizing compilers *lwn.net*.  11.10.2019. Viitattu 25.11.2021. (englanniksi)
63. ↑  Paolo Bonzini: Lockless patterns: an introduction to compare-and-swap *lwn.net*.  12.3.2021. Viitattu 25.11.2021. (englanniksi)
64. ↑  Paolo Bonzini: Lockless patterns: full memory barriers *lwn.net*.  5.3.2021. Viitattu 25.11.2021. (englanniksi)
65. 1 2  Starvation and Livelock *docs.oracle.com*. Viitattu 23.11.2019. (englanniksi)
66. ↑  E. A Ashcroft: Proving Assertions about Parallel Program (PDF) *core.ac.uk*.  19.1.1973. Viitattu 23.11.2019. (englanniksi)
67. ↑  Steven Rostedt: Real-Time is coming to Linux (PDF) *events19.linuxfoundation.org*.  24.10.2018. Viitattu 26.10.2019. (englanniksi)
68. ↑  RT-mutex subsystem with PI support *kernel.org*. Viitattu 27.11.2021. (englanniksi)

Aiheesta muualla
----------------

* Paul McKenneyn RCU sivut (englanniksi)

Käännös suomeksiKäännös suomeksi Tämä artikkeli tai sen osa on käännetty tai siihen on haettu tietoja muunkielisen Wikipedian artikkelista.   
Alkuperäiset artikkelit: en:Synchronization (computer science) & en:Lock (computer science)