Sperre (Informatik)

Im Informatik, a sperren oder Mutex (aus gegenseitiger Ausschluss) ist ein Synchronisation Primitive: Ein Mechanismus, der Grenzen des Zugangs zu einer Ressource erzwingt, wenn es viele gibt Ausführungsfäden. Ein Schloss wurde entwickelt, um einen gegenseitigen Ausschluss durchzusetzen Parallelitätskontrolle Die Richtlinie und mit einer Vielzahl möglicher Methoden gibt es mehrere eindeutige Implementierungen für verschiedene Anwendungen.

Typen

Im Allgemeinen sind Schlösser Beratungsschlösser, wobei jeder Thread kooperiert, indem er die Sperre erfasst, bevor er auf die entsprechenden Daten zugegriffen hat. Einige Systeme implementieren auch Obligatorische Schlösser, wo der Versuch unbefugter Zugang zu einer verschlossenen Ressource einen erzwingen wird Ausnahme in der Einheit, die versucht, den Zugang zu erfüllen.

Die einfachste Art von Schloss ist ein binär Semaphor. Es bietet exklusiven Zugriff auf die gesperrten Daten. Andere Systeme bieten ebenfalls gemeinsamen Zugriffszugriffe für das Lesen von Daten. Andere weit verbreitete Zugriffsmodi sind exklusiv, beabsichtigt und beabsichtigt und beabsichtigt.

Eine andere Möglichkeit, Schlösser zu klassifizieren, besteht darin, was passiert, wenn die Sperrstrategie den Fortschritt eines Threads verhindert. Die meisten Verriegelungsdesigns Block das Hinrichtung des Faden Anfordern des Schlosses, bis es auf die gesperrte Ressource zugreifen darf. Mit einer Spinlock, der Faden wartet einfach ("Spins"), bis das Schloss verfügbar ist. Dies ist effizient, wenn Threads für kurze Zeit blockiert werden, da es den Overhead of Betriebssystemprozess neu platziert. Es ist ineffizient, wenn das Schloss für eine lange Zeit gehalten wird oder wenn der Fortschritt des Fadens, der das Schloss hält, von der Präsentation des gesperrten Fadens abhängt.

Sperren erfordern in der Regel den Hardwareunterstützung für eine effiziente Implementierung. Diese Unterstützung erfolgt normalerweise in Form eines oder mehrerer Atomic Anweisungen wie "testen und einstellen","Fetch-and-add" oder "vergleiche und swap"Diese Anweisungen ermöglichen es einem einzelnen Prozess, zu testen, ob die Sperre kostenlos ist, und erwerben Sie die Sperre in einem einzelnen Atombetrieb.

Uniprozessor Architekturen haben die Möglichkeit, unterbrechungsfreie Anweisungen zu verwenden, um spezielle Anweisungen oder Anweisungen zu verwenden, um Interrupts vorübergehend zu deaktivieren - aber diese Technik funktioniert nicht für Multiprozessor gemeinsame Memory-Maschinen. Die ordnungsgemäße Unterstützung für Sperren in einer Multiprozessor -Umgebung kann eine ziemlich komplexe Hardware- oder Software -Unterstützung erfordern, mit wesentlicher Bedeutung Synchronisation Ausgaben.

Der Grund und Atombetrieb ist erforderlich, wenn mehr als eine Aufgabe dieselbe Logik ausführt. Betrachten Sie beispielsweise Folgendes C Code:

wenn (sperren == 0) {   // frei sperren, setzen   sperren = mypid; } 

Das obige Beispiel garantiert nicht, dass die Aufgabe die Sperre hat, da mehr als eine Aufgabe das Sperre gleichzeitig testen kann. Da beide Aufgaben feststellen, dass das Schloss kostenlos ist, versuchen beide Aufgaben, das Schloss festzulegen, ohne zu wissen, dass die andere Aufgabe auch die Einstellung des Schlosses. Dekkers oder Petersons Algorithmus sind mögliche Substitute, wenn Atomsperrvorgänge nicht verfügbar sind.

Die unachtsame Verwendung von Schlössern kann dazu führen Sackgasse oder Lebensunterhalt. Eine Reihe von Strategien kann verwendet werden, um Deadlocks oder Lebensunterlagen sowohl zur Entwurfszeit als auch bei der Entwurfszeit zu vermeiden oder zu erholen Laufzeit. (Die häufigste Strategie besteht darin, die Sperraufnahmesequenzen so zu standardisieren, dass Kombinationen von interunabhängigen Schlössern immer in einer spezifisch definierten "Kaskade" -Sordnung erfasst werden.)

Einige Sprachen unterstützen Sperren syntaktisch. Ein Beispiel in C# folgt:

Öffentlichkeit Klasse Konto // Dies ist ein Monitor eines Kontos {  Privatgelände Dezimal _Gleichgewicht = 0;  Privatgelände Objekt _Balancelock = Neu Objekt();  Öffentlichkeit Leere Kaution(Dezimal Menge)  {  // kann diese Anweisung ausführen.  sperren (_Balancelock)  {  _Gleichgewicht += Menge;  }  }  Öffentlichkeit Leere Abheben(Dezimal Menge)  {  // kann diese Anweisung ausführen.  sperren (_Balancelock)  {  _Gleichgewicht -= Menge;  }  } } 

Der Code Sperren (dies) kann zu Problemen führen, wenn auf die Instanz öffentlich zugegriffen werden kann.[1]

Ähnlich zu Java, C# kann auch ganze Methoden mithilfe der methodimploptions.synchronisierten Attribut synchronisieren.[2][3]

[Methodimpl (methodimploptions.ynchronized)]] Öffentlichkeit Leere Somemethod() {  // Sachen machen } 

Die Granularität

Bevor man vorgestellt wird, um die Granularität zu sperren, muss man drei Konzepte über Schlösser verstehen:

  • Sperrsperrung: Die zusätzlichen Ressourcen für die Verwendung von Schlösser wie dem Speicherplatz für Schlösser, der CPU -Zeit zum Initialisieren und Zerstören von Schlössern sowie die Zeit für den Erwerb oder die Freigabe von Schlösser. Je mehr ein Programm verwendet, desto mehr Overhead für die Verwendung verbunden ist.
  • sperren Streit: Dies geschieht immer dann, wenn ein Prozess oder Faden versucht, eine von einem anderen Prozess oder Faden gehaltene Schloss zu erwerben. Je feinkörniger die verfügbaren Sperren, desto weniger wahrscheinlich wird ein Vorgang/Thread eine von der andere gehaltene Schloss anfordern. (Zum Beispiel eher eine Zeile anstelle der gesamten Tabelle oder eine Zelle anstelle der gesamten Zeile sperren);
  • Sackgasse: Die Situation, in der jeweils mindestens zwei Aufgaben auf ein Schloss wartet, das die andere Aufgabe hält. Wenn etwas nicht erledigt ist, werden die beiden Aufgaben ewig warten.

Es gibt einen Kompromiss zwischen abnehmender Sperraufwand und einer abnehmenden Verringerung bei der Auswahl der Anzahl der in der Synchronisation ausgewählten Schlösser.

Eine wichtige Eigenschaft eines Schlosses ist seine Die Granularität. Die Granularität ist ein Maß für die Datenmenge, die die Sperre schützt. Im Allgemeinen führt die Auswahl einer groben Granularität (eine kleine Anzahl von Schlössern, die jeweils ein großes Datensegment schützen) zu weniger Sperrsperrung Wenn ein einzelner Prozess auf die geschützten Daten zugreift, aber eine schlechtere Leistung, wenn mehrere Prozesse gleichzeitig ausgeführt werden. Dies liegt an erhöhten Erhöhungen Streit sperren. Je grober das Schloss ist, desto höher ist die Wahrscheinlichkeit, dass das Schloss einen nicht verwandten Prozess am Fortschreiten hat. Umgekehrt erhöht die Verwendung einer feinen Granularität (eine größere Anzahl von Schlössern, die jeweils eine ziemlich geringe Datenmenge schützen) den Overhead der Schlösser selbst, verringert jedoch die Konkurrenz von Schloss. Granulare Verriegelung, bei der jedes Prozess mehrere Schlösser von einem gemeinsamen Satz von Schlössern enthalten muss, kann subtile Sperrabhängigkeiten erzeugen. Diese Subtilität kann die Wahrscheinlichkeit erhöhen, dass ein Programmierer unwissentlich a einführt Sackgasse.

In einem DatenbankverwaltungssystemZum Beispiel könnte ein Schloss in der Reihenfolge der Verringerung der Granularität, eines Teils eines Feldes, eines Feldes, eines Datensatzes, einer Datenseite oder einer gesamten Tabelle schützen. Die grobe Granularität, wie beispielsweise die Verwendung von Tabellenschlössern, bietet tendenziell die beste Leistung für einen einzelnen Benutzer, während eine feine Granularität, wie z. B. Aufzeichnungsschlösser, tendenziell die beste Leistung für mehrere Benutzer liefert.

Datenbankschlösser

Datenbankschlösser kann als Mittel zur Gewährleistung der Transaktionssynchronizität verwendet werden. d.h. bei gleichzeitiger Verarbeitung von Transaktionen (Verschachtung von Transaktionen) verwendet, verwenden 2-phased-Schlösser stellt sicher, dass die gleichzeitige Ausführung der Transaktion einer seriellen Reihenfolge der Transaktion entspricht. Deadlocks werden jedoch zu einem unglücklichen Nebeneffekt der Sperren in Datenbanken. Deadlocks werden entweder verhindert, indem die Verriegelungsreihenfolge zwischen Transaktionen vorbestimmt oder verwendet wird Warten für Grafiken. Eine Alternative zum Sperren für die Datenbanksynchronizität und das Vermeiden von Deadlocks beinhaltet die Verwendung vollständig geordneter globaler Zeitstempel.

Es gibt Mechanismen, die zur Verwaltung der Aktionen von mehreren verwendet werden gleichzeitige Benutzer Auf einer Datenbank - der Zweck ist es, verlorene Updates und schmutzige Lesevorgänge zu verhindern. Die beiden Arten von Sperren sind Pessimistische Verriegelung und Optimistisches Sperren:

  • Pessimistische Verriegelung: Ein Benutzer, der einen Datensatz liest, um ihn zu aktualisieren, legt ein exklusives Sperre für den Datensatz ab, um zu verhindern, dass andere Benutzer diese manipulieren. Dies bedeutet, dass niemand sonst diesen Aufzeichnung manipulieren kann, bis der Benutzer das Schloss veröffentlicht. Der Nachteil ist, dass Benutzer sehr lange gesperrt werden können, wodurch die Reaktion des Gesamtsystems verlangsamt und Frustration verursacht wird.
Wo können Sie pessimistische Sperren verwenden: Dies wird hauptsächlich in Umgebungen verwendet, in denen die Dateneinrichtung (der Grad der Benutzer zu einem Zeitpunkt an das Datenbanksystem anfordert) schwer ist. Wenn die Kosten für den Schutz von Daten durch Schlösser geringer sind als die Kosten für die Rücksendung von Transaktionen, wenn Konflikte auftreten. Die pessimistische Parallelität wird am besten implementiert, wenn die Schließzeiten kurz sind, wie bei der programmatischen Verarbeitung von Datensätzen. Pessimistische Parallelität erfordert eine anhaltende Verbindung zur Datenbank und ist keine skalierbare Option, wenn Benutzer mit Daten interagieren, da Datensätze möglicherweise für relativ große Zeiträume gesperrt werden. Es ist nicht geeignet, um die Entwicklung von Webanwendungen zu verwenden.
  • Optimistisches Sperren: Dies ermöglicht mehrere gleichzeitige Benutzer, die auf die Datenbank zugreifen, während das System eine Kopie des von jedem Benutzer erstellten Anfangs-Lesens aufbewahrt. Wenn ein Benutzer einen Datensatz aktualisieren möchte, stellt die Anwendung fest, ob ein anderer Benutzer den Datensatz seit dem letzten Lesen geändert hat. Die Anwendung vergleicht das im Speicher gelegene anfängliche Lesen mit dem Datenbankdatensatz, um alle Änderungen am Datensatz zu überprüfen. Alle Unstimmigkeiten zwischen dem anfänglichen Lesen und dem Datenbankdatensatz verstoßen gegen Parallelitätsregeln und veranlassen daher das System, eine Aktualisierungsanforderung zu ignorieren. Es wird eine Fehlermeldung generiert und der Benutzer wird aufgefordert, den Aktualisierungsprozess erneut zu starten. Es verbessert die Datenbankleistung durch Reduzierung der erforderlichen Sperren, wodurch die Last auf dem Datenbankserver verringert wird. Es funktioniert effizient mit Tabellen, die begrenzte Updates erfordern, da keine Benutzer gesperrt sind. Einige Aktualisierungen können jedoch fehlschlagen. Der Nachteil sind konstante Aktualisierungsfehler aufgrund hoher Mengen an Aktualisierungsanforderungen mehrerer gleichzeitiger Benutzer - es kann für Benutzer frustrierend sein.
Wo zu optimistischer Sperre verwendet werden: Dies ist in Umgebungen geeignet, in denen nur geringe Daten für Daten vorliegen oder in denen nur schreibgeschützte Zugriff auf Daten erforderlich ist. Die optimistische Parallelität wird in .NET ausgiebig verwendet, um die Anforderungen von mobilen und getrennten Anwendungen zu befriedigen.[4] Wenn die Verriegelung von Datenzeilen über längere Zeiträume versperrt wären, wären nicht realisierbar. Die Wartung von Datensatzsperren erfordert auch eine anhaltende Verbindung zum Datenbankserver, was in nicht verbundenen Anwendungen nicht möglich ist.

Nachteile

Sperrbasierte Ressourcenschutz und Thread-/Prozess-Synchronisation haben viele Nachteile:

  • Auseinandersetzung: Einige Threads/Prozesse müssen warten, bis ein Schloss (oder eine ganze Reihe von Schlössern) freigegeben wird. Wenn einer der Fäden, die ein Schloss halten, stirbt, stillt, blockiert oder in eine unendliche Schleife eingeht, können andere Fäden, die auf das Schloss warten, auf unbestimmte Zeit warten, bis der Computer ist Power Cycling.
  • Overhead: Die Verwendung von Schlössern fügt für jeden Zugriff auf eine Ressource Overhead hinzu, auch wenn die Kollisionswahrscheinungen sehr selten sind. (Jede Chance für solche Kollisionen ist jedoch a Rassenbedingung.))
  • Debugging: Fehler, die mit Schlösser verbunden sind, sind zeitabhängig und können sehr subtil und äußerst schwer zu replizieren sein, wie z. Deadlocks.
  • Instabilität: Das optimale Gleichgewicht zwischen Sperraufwand und Konkurrenz von Schloss kann einzigartig für die Problemdomäne (Anwendung) und empfindlich für Design-, Implementierungs- und sogar niedrigstufige Systemarchitekturänderungen sein. Diese Guthaben können sich im Laufe des Lebenszyklus einer Anwendung ändern und können enorme Änderungen zur Aktualisierung (Neuausgleich) bedeuten.
  • Kompositionsfähigkeit: Sperren sind nur komponierbar (z. B. Verwalten mehrerer gleichzeitiger Schlösser, um Element X aus Tabelle A atomar zu löschen und X in Tabelle B) mit relativ ausgefeilter (Overhead) -Softwareunterstützung und perfekter Einhaltung durch Anwendungen durch Anwendungen mit strengen Konventionen zu löschen.
  • Prioritätsinversion: Ein Faden/Verfahren mit niedriger Priorität, der eine gemeinsame Sperre hält, kann verhindern, dass Fäden/Prozesse mit hoher Priorität fortfahren. Prioritätsvererbung Kann verwendet werden, um die Prioritätsinversionsdauer zu reduzieren. Das Prioritätsprotokoll kann auf uniprozessorsystemen verwendet werden Sackgasse.
  • Konvoiing: Alle anderen Threads müssen warten, wenn ein Faden, der ein Schloss hält, aufgrund eines Zeitklappen-Interrupts oder eines Seitenfehlers entnommen wird.

Etwas Parallelitätskontrolle Strategien vermeiden einige oder alle dieser Probleme. Zum Beispiel a Trichter oder Serialisierende Token kann das größte Problem vermeiden: Deadlocks. Alternativen zur Verriegelung umfassen Nicht blockierende Synchronisation Methoden wie lockfrei Programmierungstechniken und Transaktionsspeicher. Solche alternativen Methoden erfordern jedoch häufig, dass die tatsächlichen Sperrmechanismen auf einer grundlegenderen Ebene der Betriebssoftware implementiert werden. Daher dürfen sie die nur entlasten Anwendung Stufe aus den Details der Implementierung von Schlösser, wobei die oben aufgeführten Probleme noch unter der Anwendung behandelt werden müssen.

In den meisten Fällen hängt die ordnungsgemäße Verriegelung von der CPU ab Die Manipulation des Speicherinhalts, das zum Hinzufügen oder Löschen des spezifischen Elements erforderlich ist). Daher kann eine Anwendung oft robuster sein, wenn sie die Belastungen an einem Betriebssystem erkennt und die Berichterstattung über unmögliche Anforderungen freundlich erkennen kann.

Mangel an Komposition

Eines der größten Probleme von Lock-basiertem Programmieren ist, dass "Schlösser nicht komponieren": Es ist schwierig, kleine, korrekte sperrenbasierte Module in ebenso korrekte größere Programme zu kombinieren, ohne die Module zu ändern oder zumindest ihre Interna zu kennen. Simon Peyton Jones (ein Befürworter von Software -Transaktionsspeicher) gibt das folgende Beispiel für einen Bankantrag an:[5] Entwerfen Sie eine Klasse Konto Dies ermöglicht es mehreren gleichzeitigen Kunden, Geld auf ein Konto einzureichen oder abzuheben. und geben Sie einen Algorithmus, um Geld von einem Konto auf ein anderes zu überweisen. Die sperrenbasierte Lösung für den ersten Teil des Problems lautet:

Klasse Konto: Mitglied Gleichgewicht: Ganzzahl Mitglied Mutex: Lock Methode Einzahlung (n: Integer) mutex.lock () Balance ← Balance + n mutex.unlock () Methode Abheben (n: Ganzzahl) Einzahlung (−n)

Der zweite Teil des Problems ist viel komplizierter. EIN Transfer Routine, die korrekt ist Für sequentielle Programme wäre

Funktion Übertragung (von: Konto, an: Konto, Betrag: Integer) von.

In einem gleichzeitigen Programm ist dieser Algorithmus falsch, da wenn ein Thread auf halbem Weg ist Transfer, ein anderer könnte einen Zustand beobachten, wo Menge wurde aus dem ersten Konto zurückgezogen, aber noch nicht auf das andere Konto eingezahlt: Geld ist im System verschwunden. Dieses Problem kann nur vollständig behoben werden, indem Sperrungen auf beide Konto aufgenommen werden, bevor sie eines der beiden Konten geändert haben. Dann müssen die Schlösser entsprechend einer willkürlichen, globalen Bestellung zur Verhinderung von Deadlocken aufgenommen werden:

Funktion Überweisung (von: Konto, an: Konto, Betrag: Ganzzahl) wenn von <bis // willkürliche Bestellung auf den Schlössern         von.lock () to.lock () anders         to.lock () von.lock () von

Diese Lösung wird komplizierter, wenn mehr Schlösser beteiligt sind und die Transfer Funktion muss über alle Schlösser informiert werden, also können sie es nicht sein versteckt.

Sprachunterstützung

Programmiersprachen unterscheiden sich in ihrer Unterstützung für die Synchronisation:

  • Ada Bietet geschützte Objekte mit sichtbaren geschützten Unterprogrammen oder Einträgen[6] sowie Rendezvous.[7]
  • Die ISO/IEC C Standard bietet einen Standard gegenseitiger Ausschluss (Schlösser) API seit C11. Die aktuelle ISO/IEC C ++ Standardunterstützungen Einrichtungen von Fäden seit C ++ 11. Das OpenMP Standard wird von einigen Compilern unterstützt und ermöglicht es, kritische Abschnitte mit Pragmas festzulegen. Das Possix pThread API bietet Sperrunterstützung.[8] Visuell c ++ Bietet die synchronisieren Attribut der zu synchronen Methoden, dies ist jedoch spezifisch für COM -Objekte in der Fenster Architektur und Visuell c ++ Compiler.[9] C und C ++ können problemlos auf native Betriebssystemverriegelungsfunktionen zugreifen.
  • C# Bietet die sperren Schlüsselwort in einem Thread, um den exklusiven Zugriff auf eine Ressource zu gewährleisten.
  • Vb.net bietet a Synclock Schlüsselwort wie C#'s sperren Stichwort.
  • Java Bietet das Schlüsselwort synchronisiert Codeblöcke sperren, Methoden oder Objekte[10] und Bibliotheken mit gleichzeitig sicheren Datenstrukturen.
  • Ziel c Bietet das Schlüsselwort @Synchronized[11] Um Sperren auf Codeblöcke zu setzen, und auch den Klassen NSLOCK bereitzustellen,[12] Nsrecursingock,[13] und NSConDitionlock[14] zusammen mit dem NSlocking -Protokoll[15] auch zum Sperren.
  • Php Bietet eine dateibasierte Sperre [16] Sowie wie a Mutex Klasse in der phreads Verlängerung. [17]
  • Python Bietet eine niedrige Ebene Mutex Mechanismus mit a Sperren Klasse aus dem Fäden Modul.[18]
  • Die ISO/IEC Forran Standard (ISO/IEC 1539-1: 2010) liefert die Schloss Typ abgeleiteter Typ im intrinsischen Modul ISO_FORTRAN_ENV und die sperren/Freischalten Aussagen seit FORTRAN 2008.[19]
  • Rubin Bietet eine niedrige Ebene Mutex Objekt und kein Schlüsselwort.[20]
  • Rost Bietet die Mutex[21] Struktur.[22]
  • x86 Montage Bietet die SPERREN Präfix für bestimmte Operationen, um ihre Atomizität zu gewährleisten.
  • Haskell implementiert das Verriegelung über eine veränderliche Datenstruktur, die als als bezeichnet wird Mvar, die entweder leer sein oder einen Wert enthalten, normalerweise einen Verweis auf eine Ressource. Ein Thread, der die Ressource "nimmt" den Wert der verwenden möchte Mvar, lasse es leer und legt es zurück, wenn es fertig ist. Versuch, eine Ressource aus einem leeren zu nehmen Mvar Ergebnisse in der Fadensperrung, bis die Ressource verfügbar ist.[23] Als Alternative zum Sperren eine Implementierung von Software -Transaktionsspeicher existiert auch.[24]
  • gehen Bietet eine niedrige Ebene Mutex Objekt in der Standardbibliothek Synchronisation Paket.[25] Es kann zum Sperren von Codeblöcken verwendet werden. Methoden oder Objekte.

Siehe auch

Verweise

  1. ^ "Sperrenanweisung (C# Referenz)".
  2. ^ "ThreadpoolPriority und methodimplattribute". Msdn. p. ?. Abgerufen 2011-11-22.
  3. ^ "C# aus der Perspektive eines Java -Entwicklers". Archiviert von das Original Am 2013-01-02. Abgerufen 2011-11-22.
  4. ^ "Entwerfen von Datenstufenkomponenten und Übergabe von Daten durch Stufe". Microsoft. August 2002. archiviert von das Original am 2008-05-08. Abgerufen 2008-05-30.
  5. ^ Peyton Jones, Simon (2007). "Schöne Parallelität" (PDF). In Wilson, Greg; Oram, Andy (Hrsg.). Schöner Code: führende Programmierer erklären, wie sie denken. O'Reilly.
  6. ^ ISO/IEC 8652: 2007. "Geschützte Einheiten und geschützte Objekte". ADA 2005 Referenzhandbuch. Abgerufen 2010-02-27. Ein geschütztes Objekt bietet einen koordinierten Zugriff auf gemeinsam genutzte Daten, indem er seine sichtbaren geschützten Operationen aufrufe, die unterprogramme oder geschützte Einträge geschützt werden können.
  7. ^ ISO/IEC 8652: 2007. "Beispiel für Aufgabe und Synchronisation". ADA 2005 Referenzhandbuch. Abgerufen 2010-02-27.
  8. ^ Marshall, Dave (März 1999). "Gegenseitige Ausschlussschlösser". Abgerufen 2008-05-30.
  9. ^ "Synchronisieren". msdn.microsoft.com. Abgerufen 2008-05-30.
  10. ^ "Synchronisation". Sun Microsystems. Abgerufen 2008-05-30.
  11. ^ "Apple Threading Referenz". Apple Inc. Abgerufen 2009-10-17.
  12. ^ "NSLOCK -Referenz". Apple Inc. Abgerufen 2009-10-17.
  13. ^ "Nsrecursingock Referenz". Apple Inc. Abgerufen 2009-10-17.
  14. ^ "NSConDitionlock Referenz". Apple Inc. Abgerufen 2009-10-17.
  15. ^ "NSLocking -Protokollreferenz". Apple Inc. Abgerufen 2009-10-17.
  16. ^ "Herde".
  17. ^ "Die Mutex -Klasse".
  18. ^ Lundh, Fredrik (Juli 2007). "Fadensynchronisationsmechanismen in Python". Archiviert von das Original am 2020-11-01. Abgerufen 2008-05-30.
  19. ^ John Reid (2010). "Coarrays im nächsten Fortran -Standard" (PDF). Abgerufen 2020-02-17.
  20. ^ "Programmieren von Ruby: Fäden und Prozesse". 2001. Abgerufen 2008-05-30.
  21. ^ "std :: sync :: mutex - rost". doc.rustlang.org. Abgerufen 3. November 2020.
  22. ^ "Parallelität mit gemeinsamer Staat - die Rost -Programmiersprache". doc.rustlang.org. Abgerufen 3. November 2020.
  23. ^ Marlow, Simon (August 2013). "Grundlegendes Parallelität: Threads und Mvars". Parallele und gleichzeitige Programmierung in Haskell. O’Reilly Media. ISBN 9781449335946.
  24. ^ Marlow, Simon (August 2013). "Software -Transaktionsspeicher". Parallele und gleichzeitige Programmierung in Haskell. O’Reilly Media. ISBN 9781449335946.
  25. ^ "Sync -Paket - Synchronisation - pkg.go.dev". pkg.go.dev. Abgerufen 2021-11-23.

Externe Links