Schloss (Informatik)

In der Informatik ist ein Schloss ein Synchronisationsmechanismus, um Grenzen beim Zugang zu einer Quelle in einer Umgebung geltend zu machen, wo es viele Fäden der Ausführung gibt. Schlösser sind eine Weise, Parallelitätskontrollpolicen geltend zu machen.

Typen

Allgemein sind Schlösser Beratungsschlösser, wo jeder Faden durch das Erwerben des Schlosses vor dem Zugreifen auf die entsprechenden Daten zusammenarbeitet. Einige Systeme führen auch obligatorische Schlösser durch, wo der Versuch unerlaubten Zugangs zu einer geschlossenen Quelle eine Ausnahme in der Entität zwingen wird, die versucht, den Zugang zu machen.

Ein (binäres) Semaphor ist der einfachste Typ des Schlosses. In Bezug auf den Zugang zu den Daten wird keine Unterscheidung zwischen dem geteilten gemacht (lesen Sie nur), oder exklusiv (gelesen und schreiben), Weisen. Andere Schemas sorgen für eine geteilte Weise, wo mehrere Fäden ein geteiltes Schloss für den Read-Only-Zugang zu den Daten erwerben können. Andere Weisen solcher als exklusiv, intend-exclude und bestimmen zu der Steigung werden auch weit durchgeführt.

Unabhängig des Typs des Schlosses, das oben gewählt ist, können Schlösser dadurch klassifiziert werden, was geschieht, wenn die Schloss-Strategie Fortschritt eines Fadens verhindert. Die meisten sich schließen lassenden Designs blockieren die Ausführung des Fadens, der um das Schloss bittet, bis es erlaubt wird, auf die geschlossene Quelle zuzugreifen. Ein spinlock ist ein Schloss, wo der Faden einfach wartet (spinnt), bis das Schloss verfügbar wird. Es ist sehr effizient, wenn Fäden nur wahrscheinlich seit einer kurzen Zeitspanne blockiert werden, weil es die Gemeinkosten der Betriebssystemprozess-Umterminierung vermeidet. Es ist verschwenderisch, wenn das Schloss seit einem langen Zeitraum der Zeit gehalten wird.

Schlösser verlangen normalerweise Hardware-Unterstützung für die effiziente Durchführung. Das nimmt gewöhnlich die Form von einer oder mehr Atominstruktionen wie "Test-Und-Satz", "herbeiholen-und-hinzufügen" oder "vergleichen-und-tauschen" an. Diese Instruktionen erlauben einem einzelnen Prozess zu prüfen, wenn das Schloss, und wenn frei, frei ist, erwerben Sie das Schloss in einer einzelnen Atomoperation.

Architekturen von Uniprocessor haben die Auswahl, unterbrechungsfreie Folgen von Instruktionen, mit speziellen Instruktionen oder Instruktionspräfixen zu verwenden, um Unterbrechungen provisorisch unbrauchbar zu machen, aber diese Technik arbeitet für Mehrverarbeiter-Maschinen des geteilten Gedächtnisses nicht. Die richtige Unterstützung für Schlösser in einer Mehrverarbeiter-Umgebung kann ziemlich komplizierte Hardware oder Softwareunterstützung mit wesentlichen Synchronisationsproblemen verlangen.

Der Grund eine Atomoperation ist erforderlich, ist wegen der Parallelität, wo mehr als eine Aufgabe dieselbe Logik durchführt. Denken Sie zum Beispiel den folgenden C-Code:

wenn (lassen sich == 0 schließen), {\

/* Schloss frei - hat es * / gesetzt

lassen Sie sich = myPID schließen;

}\

</Quelle>

Das obengenannte Beispiel versichert nicht, dass die Aufgabe das Schloss hat, da mehr als eine Aufgabe das Schloss zur gleichen Zeit prüfen kann. Da beide Aufgaben entdecken werden, dass das Schloss frei ist, beide Aufgaben versuchen werden, das Schloss zu setzen, nicht wissend, dass die andere Aufgabe auch das Schloss setzt. Der Algorithmus von Dekker oder Petersons ist möglicher Ersatz, wenn sich schließen lassende Atomoperationen nicht verfügbar sind.

Der unbesonnene Gebrauch von Schlössern kann auf toten Punkt oder livelock hinauslaufen. Mehrere Strategien können verwendet werden, um zu vermeiden oder sich von toten Punkten oder livelocks sowohl am designmaligen als auch an der Durchlaufzeit zu erholen. (Das allgemeinste soll die Schloss-Erwerb-Folgen standardisieren, so dass Kombinationen von voneinander abhängigen Schlössern immer erworben und in einer spezifisch definierten "Kaskade"-Ordnung veröffentlicht werden.)

Einige Sprachen unterstützen wirklich Schlösser syntaktisch. Ein Beispiel in C# folgt:

Klassenrechnung {//das ist ein Monitor einer Rechnung

langer val = 0;

wenden Sie thisLock = neuer Gegenstand ein;

öffentliche leere Ablagerung (const langer x) {\

Schloss (thisLock) {//nur 1 Faden kann auf einmal diese Behauptung durchführen

val + = x;

}\

}\

öffentliche Leere Zieht (const langer x) {\Zurück

Schloss (thisLock) {\

val - = x;

}\ }\}\</Quelle>

lassen Sie sich schließen (das) ist ein Problem, wenn auf das Beispiel öffentlich zugegriffen werden kann.

Ähnlich nach Java, C# kann auch komplette Methoden, durch das Verwenden von MethodImplOptions synchronisieren. Synchronisiertes Attribut.

[MethodImpl (MethodImplOptions. Synchronisiert)]

öffentlicher leerer SomeMethod {\

//stopfen Sie wirklich voll

}

</Quelle>

Körnung

Bevor

man eingeführt wird, um Körnung zu schließen, muss man drei Konzepte über Schlösser verstehen.

  • lassen Sie sich oben schließen: Die Extramittel, um Schlösser wie der Speicherraum zu verwenden, der für Schlösser, die Zentraleinheitszeit zugeteilt ist, um Schlösser, und die Zeit zu initialisieren und zu zerstören, um Schlösser zu erwerben oder zu veröffentlichen. Je mehr Schlösser, die ein Programm verwendet, desto mehr oberirdisch mit dem Gebrauch verkehrt hat.
  • Schloss-Streit: Das kommt vor, wann auch immer ein Prozess oder Faden versuchen, ein Schloss zu erwerben, das durch einen anderen Prozess oder Faden gehalten ist. Je mehr granuliert die verfügbaren Schlösser, desto weniger wahrscheinlich ein Prozess/Faden um ein durch den anderen gehaltenes Schloss bitten wird. (Zum Beispiel, eine Reihe aber nicht den kompletten Tisch schließend, oder eine Zelle aber nicht die komplette Reihe schließend.)
  • toter Punkt: Die Situation, wenn jede von zwei Aufgaben auf ein Schloss wartet, das die andere Aufgabe hält. Wenn etwas nicht getan wird, werden die zwei Aufgaben für immer warten.

Es gibt einen Umtausch zwischen dem abnehmenden Schloss oben und Schloss-Streit vermindernd, wenn es die Zahl von Schlössern in der Synchronisation wählt.

Ein wichtiges Eigentum eines Schlosses ist seine Körnung. Die Körnung ist ein Maß der Datenmenge, die das Schloss schützt. Im Allgemeinen läuft das Wählen einer rauen Körnung (eine kleine Zahl von Schlössern, jeder, ein großes Segment von Daten schützend), auf weniger Schloss oben hinaus, wenn ein einzelner Prozess auf die geschützten Daten zugreift, aber schlechtere Leistung, wenn vielfache Prozesse gleichzeitig laufen. Das ist wegen des vergrößerten Schloss-Streits. Je rauer das Schloss, desto höher die Wahrscheinlichkeit, dass das Schloss einen Prozess ohne Beziehung verhindern wird weiterzugehen. Umgekehrt vergrößert das Verwenden einer feinen Körnung (eine größere Zahl von Schlössern, jeder, eine ziemlich kleine Datenmenge schützend), die Gemeinkosten der Schlösser selbst, aber reduziert Schloss-Streit. Granulierte Blockierung, wo jeder Prozess vielfache Schlösser von einem Standardset von Schlössern halten muss, kann feine Schloss-Abhängigkeiten schaffen. Diese Subtilität kann die Chance vergrößern, dass ein Programmierer einen toten Punkt unbewusst einführen wird.

In einem Datenbankverwaltungssystem, zum Beispiel, konnte ein Schloss, in der Größenordnung von der abnehmenden Körnung, dem Teil eines Feldes, eines Feldes, einer Aufzeichnung, einer Datenseite oder eines kompletten Tisches schützen. Raue Körnung, wie das Verwenden von Tabellenschlössern, neigt dazu, die beste Leistung für einen einzelnen Benutzer zu geben, wohingegen feine Körnung, wie Datensatzsperren, dazu neigt, die beste Leistung für vielfache Benutzer zu geben.

Datenbankschlösser

Datenbankschlösser können als ein Mittel verwendet werden, Transaktion synchronicity. zu sichern, d. h. wenn man Transaktion macht, die gleichzeitig in einer Prozession geht (das Durchschießen von Transaktionen), das Verwenden von 2 aufeinander abgestimmten Schlössern stellt sicher, dass sich die gleichzeitige Ausführung der Transaktion gleichwertig zu etwas Serieneinrichtung der Transaktion erweist. Jedoch werden tote Punkte eine unglückliche Nebenwirkung der Blockierung in Datenbanken. Tote Punkte werden entweder durch das Vorherbestimmen der sich schließen lassenden Ordnung zwischen Transaktionen verhindert oder werden damit entdeckt wartet - auf Graphen. Ein Stellvertreter zur Blockierung für die Datenbank synchronicity, während er tote Punkte vermeidet, schließt den Gebrauch völlig bestellter globaler Zeitstempel ein.

Es gibt Mechanismen, die verwendet sind, um die Handlungen von vielfachen gleichzeitigen Benutzern auf einer Datenbank zu führen - der Zweck ist, verlorene Aktualisierungen zu verhindern, und schmutzig liest. Die zwei Typen der Blockierung sind Pessimistische und Optimistische Blockierung.

  • Pessimistische Blockierung: Ein Benutzer, der eine Aufzeichnung mit der Absicht liest, es zu aktualisieren, legt ein exklusives Schloss auf der Aufzeichnung, um andere Benutzer davon abzuhalten, sie zu manipulieren. Das bedeutet, dass keiner anderer diese Aufzeichnung manipulieren kann, bis der Benutzer das Schloss veröffentlicht. Die Kehrseite ist, dass Benutzer seit einer sehr langen Zeit ausgesperrt werden können, dadurch die gesamte Systemantwort verlangsamend und Frustration verursachend.
  • Wo man pessimistische Blockierung verwendet: Das wird in Umgebungen hauptsächlich verwendet, wo Datenstreit (der Grad von Benutzern bitten zum Datenbanksystem zu irgendeiner Zeit), schwer ist; wo die Kosten, Daten durch Schlösser zu schützen, weniger sind als die Kosten, Transaktionen zu wiederholen, wenn Parallelitätskonflikte vorkommen. Pessimistische Parallelität wird am besten durchgeführt, wenn Schloss-Zeiten, als in der Programmatic-Verarbeitung von Aufzeichnungen kurz sein werden. Pessimistische Parallelität verlangt eine beharrliche Verbindung zur Datenbank und ist nicht eine ersteigbare Auswahl, wenn Benutzer mit Daten aufeinander wirken, weil Aufzeichnungen seit relativ großen Zeitspannen geschlossen werden könnten. Es ist für den Gebrauch in der Webanwendungsentwicklung nicht passend.
  • Optimistische Blockierung: Das erlaubt vielfachen gleichzeitigen Benutzerzugang zur Datenbank, während das System eine Kopie des von jedem Benutzer gemachten Initiale-gelesenen hält. Wenn ein Benutzer eine Aufzeichnung aktualisieren will, bestimmt die Anwendung, ob ein anderer Benutzer die Aufzeichnung geändert hat, seitdem es gelesen letzt war. Die Anwendung tut das durch das Vergleichen des Initiale-gelesenen, das im Gedächtnis zur Datenbank gehalten ist, registriert, um irgendwelche mit der Aufzeichnung vorgenommenen Änderungen nachzuprüfen. Irgendwelche Diskrepanzen zwischen dem Initiale-gelesenen und der Datenbankaufzeichnung verletzen Parallelitätsregeln und veranlassen folglich das System, jede Aktualisierungsbitte zu ignorieren. Eine Fehlermeldung wird erzeugt, und der Benutzer wird gebeten, den Aktualisierungsprozess wieder anzufangen. Es verbessert Datenbankleistung durch das Reduzieren des Betrags, sich erforderlich schließen zu lassen, dadurch die Last auf dem Datenbankserver reduzierend. Es arbeitet effizient mit Tischen, die beschränkte Aktualisierungen verlangen, da keine Benutzer ausgesperrt werden. Jedoch können einige Aktualisierungen scheitern. Die Kehrseite ist unveränderliche Aktualisierungsmisserfolge wegen Großserien von Aktualisierungsbitten von vielfachen gleichzeitigen Benutzern - es kann für Benutzer enttäuschend sein.
  • Wo man optimistische Blockierung verwendet: Das ist in Umgebungen passend, wo es niedrigen Streit für Daten gibt, oder wo der Read-Only-Zugang zu Daten erforderlich ist. Optimistische Parallelität wird umfassend in.NET verwendet, um die Bedürfnisse nach beweglichen und getrennten Anwendungen zu richten, wo die Blockierung von Datenreihen seit anhaltenden Zeitspannen unausführbar sein würde. Außerdem das Aufrechterhalten von Datensatzsperren verlangt eine beharrliche Verbindung zum Datenbankserver, der in getrennten Anwendungen nicht möglich ist.

Die Probleme mit Schlössern

Schloss-basierter Quellenschutz und Synchronisation des Fadens/Prozesses haben viele Nachteile:

  • Sie verursachen das Blockieren, was bedeutet, dass einige Fäden/Prozesse warten müssen, bis ein Schloss (oder ein ganzer Satz von Schlössern) veröffentlicht wird.
  • Das Schloss-Berühren trägt oben für jeden Zugang zu einer Quelle bei, selbst wenn die Chancen für die Kollision sehr selten sind. (Jedoch ist jede Chance für solche Kollisionen eine Rasse-Bedingung.)
  • Schlösser können für Misserfolge und Schulden verwundbar sein, die häufig sehr fein sind und schwierig sein können, sich zuverlässig zu vermehren. Ein Beispiel ist der tote Punkt, wo (mindestens) zwei Fäden, auf die alle für ein Schloss warten, das ein anderer Faden hält und herauf bis es nicht geben wird, das andere Schloss erworben haben.
  • Wenn ein Faden, der ein Schloss hält, stirbt, stecken/blockiert bleibt oder in eine Sorte der unendlichen Schleife eintritt, können andere Fäden, die auf das Schloss warten, für immer warten.
  • Schloss-Streit beschränkt Skalierbarkeit und fügt Kompliziertheit hinzu.
  • Gleichgewichte zwischen Schloss oben und Streit können zu gegebenen Problem-Gebieten (Anwendungen) einzigartig sowie empfindlich sein, um, Durchführung und sogar auf niedriger Stufe System architektonische Änderungen zu entwickeln. Diese Gleichgewichte können den Lebenszyklus jeder gegebenen Anwendung/Durchführung umstellen und können zur Folge haben, dass enorme Änderungen, um zu aktualisieren (wiederbalancieren).
  • Schlösser sind nur composable (z.B, vielfache gleichzeitige Schlösser führend, um Artikel X vom Tisch A atomar zu löschen und X in die Tabelle B einzufügen) mit der relativ wohl durchdachten (oberirdischen) Softwareunterstützung und vollkommenen Anhänglichkeit durch die Anwendungsprogrammierung zur strengen Vereinbarung.
  • Vorzugsinversion. Hohe Vorzugsfäden/Prozesse können nicht weitergehen, wenn ein niedriger Vorzugsfaden/Prozess das allgemeine Schloss hält.
  • Das Eskortieren. Alle anderen Fäden müssen warten, wenn ein Faden, der ein Schloss hält, wegen einer Zeitabschnitt-Unterbrechung oder Seitenschuld descheduled ist (Sieh Schloss-Konvoi)
  • Hart die Fehler zu beseitigen: Mit Schlössern vereinigte Programmfehler sind zeitabhängig. Sie sind äußerst hart zu wiederholen.
  • Es muss genügend Mittel - exklusiv gewidmetes Gedächtnis, echt oder virtuell - verfügbar für die sich schließen lassenden Mechanismen geben, ihre Zustandinformation als Antwort auf eine unterschiedliche Zahl von gleichzeitigen Beschwörungen aufrechtzuerhalten, ohne die die Mechanismen, oder "Unfall" scheitern werden, der alles abhängig von ihnen herunterbringt und das Betriebsgebiet herunterbringt, in dem sie wohnen. "Misserfolg" ist besser als Unfall, was bedeutet, dass ein richtiger sich schließen lassender Mechanismus im Stande sein sollte, "unfähig zurückzukehren, Schloss dafür zu erhalten

Einige Menschen verwenden eine Parallelitätskontrollstrategie, die einige oder alle diese Probleme nicht hat. Zum Beispiel verwenden einige Menschen einen Trichter oder in Fortsetzungen veröffentlichende Jetons, der ihre Software geschützt zum größten Problem — tote Punkte macht. Andere Leute vermeiden Schlösser völlig — das Verwenden blockierungsfreier Synchronisationsmethoden, wie Programmiertechniken ohne Schlösser und transactional Gedächtnis. Jedoch haben viele der obengenannten Nachteile Entsprechungen mit diesen alternativen Synchronisationsmethoden.

Jede solche "Parallelitätskontrollstrategie" würde wirkliche an einem grundsätzlicheren Niveau der Betriebssoftware durchgeführte Schloss-Mechanismen verlangen (die Entsprechungen, die oben erwähnt sind), der nur das Anwendungsniveau von den Details der Durchführung erleichtern kann. Die "Probleme" bleiben, aber werden unter der Anwendung befasst. Tatsächlich hängt richtige Blockierung schließlich von der Zentraleinheitshardware ab, die selbst eine Methode der Atominstruktionsstrom-Synchronisation zur Verfügung stellt. Zum Beispiel verlangen die Hinzufügung oder das Auswischen eines Artikels in eine Rohrleitung, dass alle gleichzeitigen Operationen, die beitragen oder andere Sachen in der Pfeife löschen müssen, während der Manipulation des Speicherinhalts aufgehoben werden, der erforderlich ist, den spezifischen Artikel hinzuzufügen oder zu löschen. Das Design einer Anwendung ist besser, wenn es die Lasten anerkennt, legt es auf ein Betriebssystem und ist dazu fähig, gnädig den Bericht von unmöglichen Anforderungen anzuerkennen.

Sprachunterstützung

Die Sprachunterstützung für die Blockierung hängt von der verwendeten Sprache ab:

  • Es gibt keine API, um mutexes im ISO/IEC Standard für C zu behandeln. Der Strom ISO C ++ Standard, C ++ 11, Unterstützungen, die Möglichkeiten einfädeln. Der Standard von OpenMP wird durch einige Bearbeiter unterstützt, und das stellt kritische anzugebende Abteilungen mit pragmas zur Verfügung. Der POSIX pthread API stellt Schloss-Unterstützung zur Verfügung, aber sein Gebrauch ist nicht aufrichtig. Visueller C ++ erlaubt, das synchronisieren Attribut im Code hinzuzufügen, um Methoden zu kennzeichnen, die synchronisiert werden müssen, aber das ist zu COM "Gegenständen" in der Windows-Architektur und Visuellem C ++ Bearbeiter spezifisch. C und C ++ können auf irgendwelche heimischen Betriebssystemblockierungseigenschaften leicht zugreifen.
  • Java stellt das Schlüsselwort zur Verfügung, das synchronisiert ist, um Schlösser auf Blöcke von Code, Methoden oder Gegenständen und Bibliotheken zu stellen, die vor der Parallelität sichere Datenstrukturen zeigen.
  • In C# Programmiersprache kann das Schloss-Schlüsselwort verwendet werden, um sicherzustellen, dass ein Faden exklusiven Zugang zu einer bestimmten Quelle hat.
  • VB.NET stellt ein Schlüsselwort von SyncLock zu demselben Zweck C# Schloss-Schlüsselwort zur Verfügung.
  • Pythonschlange stellt kein Schloss-Schlüsselwort zur Verfügung, aber es ist möglich, eine niedrigere Ebene mutex Mechanismus zu verwenden, ein Schloss zu erwerben oder zu veröffentlichen.
  • Rubin stellt auch kein Schlüsselwort für die Synchronisation zur Verfügung, aber es ist möglich, eine ausführliche niedrige Stufe mutex Gegenstand zu verwenden.
  • Im x86 Zusammenbau hält das SCHLOSS-Präfix einen anderen Verarbeiter davon ab, irgendetwas in der Mitte bestimmter Operationen zu tun: Es versichert atomicity.
  • Ziel-C stellt das Schlüsselwort "@synchronized" zur Verfügung, um Schlösser auf Blöcke des Codes zu stellen, und stellt auch den Klassen NSLock, NSRecursiveLock und NSConditionLock zusammen mit dem NSLocking Protokoll zur Verfügung, um sich ebenso schließen zu lassen.
Es
  • lohnt sich wahrscheinlich, auf Ada auch für eine umfassende Übersicht, mit seinen geschützten Gegenständen und Rendezvous zu schauen.

Siehe auch

Links

  • Tutorenkurs auf Schlössern und kritischen Abteilungen
http://www.futurechips.org/tips-for-power-coders/parallel-programming-understanding-impact-critical-sections.html

Tierkreis (Roman) / Golf von Ob
Impressum & Datenschutz