Hinzufügen einer Anmerkung zum SperrverhaltenAnnotating Locking Behavior

Um Parallelitäts Fehler in Ihrem Multithread-Programm zu vermeiden, befolgen Sie immer eine angemessene Sperr Disziplin, und verwenden Sie SAL-Anmerkungen.To avoid concurrency bugs in your multithreaded program, always follow an appropriate locking discipline and use SAL annotations.

Parallelitäts Fehler sind bekanntermaßen schwer zu reproduzieren, zu diagnostizieren und zu debuggen, da Sie nicht deterministisch sind.Concurrency bugs are notoriously hard to reproduce, diagnose, and debug because they are non-deterministic. Die Argumentation der Thread Interaktion ist am besten schwierig und ist nicht mehr praktikabel, wenn Sie einen Code Körper entwerfen, der mehr als einige Threads enthält.Reasoning about thread interleaving is difficult at best, and becomes impractical when you are designing a body of code that has more than a few threads. Daher empfiehlt es sich, eine Sperr Disziplin in ihren Multithreadprogrammen zu befolgen.Therefore, it's good practice to follow a locking discipline in your multithreaded programs. Wenn Sie z. b. eine Sperr Reihenfolge während des Erstellens mehrerer Sperren einhalten, können Deadlocks vermieden werden, und das Abrufen der richtigen Schutzsperre, bevor Sie auf eine freigegebene Ressource zugreifen, hilftFor example, obeying a lock order while acquiring multiple locks helps avoid deadlocks, and acquiring the proper guarding lock before accessing a shared resource helps prevent race conditions.

Leider können scheinbar einfache Sperr Regeln in der Praxis erstaunlich schwer befolgt werden.Unfortunately, seemingly simple locking rules can be surprisingly hard to follow in practice. Eine grundlegende Einschränkung in den heutigen Programmiersprachen und Compilern besteht darin, dass Sie die Spezifikation und die Analyse der Parallelitäts Anforderungen nicht direkt unterstützen.A fundamental limitation in today's programming languages and compilers is that they do not directly support the specification and analysis of concurrency requirements. Programmierer müssen sich auf informelle Code Kommentare verlassen, um Ihre Absichten in Bezug auf die Verwendung von Sperren auszudrücken.Programmers have to rely on informal code comments to express their intentions about how they use locks.

Parallelitäts SAL-Anmerkungen sind so konzipiert, dass Sie das Sperren von Nebeneffekten, die Sperr Verantwortung, die Daten Überwachungen, die Hierarchie der Sperr Reihenfolge und ein anderes erwartetes Sperr Verhalten angeben können.Concurrency SAL annotations are designed to help you specify locking side effects, locking responsibility, data guardianship, lock order hierarchy, and other expected locking behavior. Durch die explizite Durchführung impliziter Regeln bieten SAL-Parallelitäts Anmerkungen eine konsistente Möglichkeit, zu dokumentieren, wie der Code Sperr Regeln verwendet.By making implicit rules explicit, SAL concurrency annotations provide a consistent way for you to document how your code uses locking rules. Neben läufigkeits Anmerkungen verbessern auch die Fähigkeit von Code Analysetools, Racebedingungen, Deadlocks, nicht übereinstimmende Synchronisierungs Vorgänge und andere feine Parallelitäts Fehler zu finden.Concurrency annotations also enhance the ability of code analysis tools to find race conditions, deadlocks, mismatched synchronization operations, and other subtle concurrency errors.

Allgemeine RichtlinienGeneral Guidelines

Mithilfe von Anmerkungen können Sie die Verträge, die durch Funktionsdefinitionen zwischen Implementierungen (Callees) und Clients (Aufrufer) impliziert werden, sowie Express invarianten und andere Eigenschaften des Programms angeben, die die Analyse weiter verbessern können.By using annotations, you can state the contracts that are implied by function definitions between implementations (callees) and clients (callers), and express invariants and other properties of the program that can further improve analysis.

SAL unterstützt viele verschiedene Arten von Sperr primitiven – z. b. kritische Abschnitte, Mutexen, Spin-Sperren und andere Ressourcen Objekte.SAL supports many different kinds of locking primitives—for example, critical sections, mutexes, spin locks, and other resource objects. Viele Parallelitäts Anmerkungen nehmen einen Sperr Ausdruck als Parameter an.Many concurrency annotations take a lock expression as a parameter. Gemäß der Konvention wird eine Sperre durch den Pfad Ausdruck des zugrunde liegenden Sperr Objekts bezeichnet.By convention, a lock is denoted by the path expression of the underlying lock object.

Einige Thread Besitz Regeln, die berücksichtigt werden sollten:Some thread ownership rules to keep in mind:

  • Dreh Sperren sind nicht gezählte sperren, die den Thread Besitz löschen.Spin locks are uncounted locks that have clear thread ownership.

  • Mutexen und wichtige Abschnitte sind gezählte Sperren mit einem eindeutigen Thread Besitz.Mutexes and critical sections are counted locks that have clear thread ownership.

  • Semaphore und Ereignisse sind gezählte sperren, die keinen eindeutigen Thread Besitz aufweisen.Semaphores and events are counted locks that do not have clear thread ownership.

Sperren von AnmerkungenLocking Annotations

In der folgenden Tabelle sind die Sperr Anmerkungen aufgeführt.The following table lists the locking annotations.

AnmerkungAnnotation BESCHREIBUNGDescription
_Acquires_exclusive_lock_(expr) Kommentiert eine Funktion und gibt an, dass die Funktion im Post-Zustand um eine exklusive Sperr Anzahl des Sperr Objekts, das durch benannt wird, inkreliert expr .Annotates a function and indicates that in post state the function increments by one the exclusive lock count of the lock object that's named by expr.
_Acquires_lock_(expr) Kommentiert eine Funktion und gibt an, dass die Funktion im Post-Zustand um eine die Sperrenanzahl des Sperr Objekts, das durch benannt wird, inkreliert expr .Annotates a function and indicates that in post state the function increments by one the lock count of the lock object that's named by expr.
_Acquires_nonreentrant_lock_(expr) Die Sperre, die von benannt expr wird, wird abgerufen.The lock that's named by expr is acquired. Wenn die Sperre bereits besteht, wird ein Fehler gemeldet.An error is reported if the lock is already held.
_Acquires_shared_lock_(expr) Kommentiert eine Funktion und gibt an, dass die Funktion im Post-Zustand um eine Anzahl der freigegebenen Sperren des Sperr Objekts, das durch benannt wird, inkreliert expr .Annotates a function and indicates that in post state the function increments by one the shared lock count of the lock object that's named by expr.
_Create_lock_level_(name) Eine Anweisung, die das Symbol name als Sperr Ebene deklariert, damit Sie in den Anmerkungen und verwendet werden kann _Has_Lock_level_ _Lock_level_order_ .A statement that declares the symbol name to be a lock level so that it may be used in the annotations _Has_Lock_level_ and _Lock_level_order_.
_Has_lock_kind_(kind) Kommentiert alle-Objekte, um die Typinformationen eines Ressourcen Objekts zu verfeinern.Annotates any object to refine the type information of a resource object. Manchmal wird ein gemeinsamer Typ für verschiedene Arten von Ressourcen verwendet, und der überladene Typ reicht nicht aus, um die semantischen Anforderungen zwischen verschiedenen Ressourcen zu unterscheiden.Sometimes a common type is used for different kinds of resources and the overloaded type is not sufficient to distinguish the semantic requirements among various resources. Im folgenden finden Sie eine Liste vordefinierter kind Parameter:Here's a list of pre-defined kind parameters:

_Lock_kind_mutex_
Sperrenkind-ID für Mutexes.Lock kind ID for mutexes.

_Lock_kind_event_
Sperrenkind-ID für Ereignisse.Lock kind ID for events.

_Lock_kind_semaphore_
Sperrenkind-ID für Semaphore.Lock kind ID for semaphores.

_Lock_kind_spin_lock_
Sperrenkind-ID für Spin-sperren.Lock kind ID for spin locks.

_Lock_kind_critical_section_
Sperrenkind-ID für kritische Abschnitte.Lock kind ID for critical sections.
_Has_lock_level_(name) Kommentiert ein Sperr Objekt und gibt ihm die Sperr Ebene von name .Annotates a lock object and gives it the lock level of name.
_Lock_level_order_(name1, name2) Eine-Anweisung, die die Sperr Anordnung zwischen name1 und ermöglicht name2 .A statement that gives the lock ordering between name1 and name2. Sperren, die über eine Ebene verfügen, name1 müssen vor Sperren mit Ebene abgerufen werden name2 .Locks that have level name1 must be acquired before locks that have level name2.
_Post_same_lock_(expr1, expr2) Kommentiert eine Funktion und gibt an, dass die beiden Sperren im Post-Zustand expr1 expr2 so behandelt werden, als wären Sie das gleiche Sperr Objekt.Annotates a function and indicates that in post state the two locks, expr1 and expr2, are treated as if they are the same lock object.
_Releases_exclusive_lock_(expr) Kommentiert eine Funktion und gibt an, dass die-Funktion im Post-Zustand um eine exklusive Sperrenanzahl des Sperr Objekts dekregiert, das von benannt wird expr .Annotates a function and indicates that in post state the function decrements by one the exclusive lock count of the lock object that's named by expr.
_Releases_lock_(expr) Kommentiert eine Funktion und gibt an, dass die-Funktion im Post-Zustand um eine Sperrenanzahl des Sperr Objekts dekregiert, das durch benannt wird expr .Annotates a function and indicates that in post state the function decrements by one the lock count of the lock object that's named by expr.
_Releases_nonreentrant_lock_(expr) Die Sperre, die von benannt expr wird, wird freigegeben.The lock that's named by expr is released. Wenn die Sperre derzeit nicht aufrechterhalten wird, wird ein Fehler gemeldet.An error is reported if the lock is not currently held.
_Releases_shared_lock_(expr) Kommentiert eine Funktion und gibt an, dass die Funktion im Post-Zustand um einen Wert für die freigegebene Sperre des Sperr Objekts, das durch benannt wird, dekregiert expr .Annotates a function and indicates that in post state the function decrements by one the shared lock count of the lock object that's named by expr.
_Requires_lock_held_(expr) Kommentiert eine Funktion und gibt an, dass die Sperrenanzahl des Objekts, das durch benannt ist, mindestens expr eins ist.Annotates a function and indicates that in pre state the lock count of the object that's named by expr is at least one.
_Requires_lock_not_held_(expr) Kommentiert eine Funktion und gibt an, dass die Sperrenanzahl des Objekts, das durch benannt ist, in der Vorbedingung expr 0 (null) ist.Annotates a function and indicates that in pre state the lock count of the object that's named by expr is zero.
_Requires_no_locks_held_ Kommentiert eine Funktion und gibt an, dass die Sperr Anzahl aller Sperren, die der Prüfung bekannt sind, 0 (null) ist.Annotates a function and indicates that the lock counts of all locks that are known to the checker are zero.
_Requires_shared_lock_held_(expr) Kommentiert eine Funktion und gibt an, dass die freigegebene Sperrenanzahl des Objekts, das durch benannt ist, mindestens expr eins ist.Annotates a function and indicates that in pre state the shared lock count of the object that's named by expr is at least one.
_Requires_exclusive_lock_held_(expr) Kommentiert eine Funktion und gibt an, dass im Voraus die exklusive Sperr Anzahl des Objekts, das durch benannt ist, mindestens expr eins ist.Annotates a function and indicates that in pre state the exclusive lock count of the object that's named by expr is at least one.

Systeminterne SAL-Funktionen für nicht verfügbare SperrobjekteSAL Intrinsics For Unexposed Locking Objects

Bestimmte Sperrobjekte werden von der Implementierung der zugehörigen Sperr Funktionen nicht verfügbar gemacht.Certain lock objects are not exposed by the implementation of the associated locking functions. In der folgenden Tabelle werden die systeminternen SAL-Variablen aufgelistet, die Anmerkungen für Funktionen ermöglichen, die für diese nicht verfügbar gemachten Sperrobjekte verwendet werden.The following table lists SAL intrinsic variables that enable annotations on functions that operate on those unexposed lock objects.

AnmerkungAnnotation BESCHREIBUNGDescription
_Global_cancel_spin_lock_ Beschreibt die Abbruch Drehsperre.Describes the cancel spin lock.
_Global_critical_region_ Beschreibt den kritischen Bereich.Describes the critical region.
_Global_interlock_ Beschreibt Interlocked-Vorgänge.Describes interlocked operations.
_Global_priority_region_ Beschreibt den Prioritäts Bereich.Describes the priority region.

Anmerkungen zum freigegebenen DatenzugriffShared Data Access Annotations

In der folgenden Tabelle sind die Anmerkungen für den Zugriff auf freigegebene Daten aufgeführt.The following table lists the annotations for shared data access.

AnmerkungAnnotation BESCHREIBUNGDescription
_Guarded_by_(expr) Kommentiert eine Variable und gibt an, dass bei jedem Zugriff auf die Variable die Sperrenanzahl des Sperr Objekts, das durch benannt ist, mindestens expr eins ist.Annotates a variable and indicates that whenever the variable is accessed, the lock count of the lock object that's named by expr is at least one.
_Interlocked_ Kommentiert eine Variable und entspricht _Guarded_by_(_Global_interlock_) .Annotates a variable and is equivalent to _Guarded_by_(_Global_interlock_).
_Interlocked_operand_ Der mit Anmerkungen versehene Funktionsparameter ist der Ziel Operand einer der verschiedenen Interlocked-Funktionen.The annotated function parameter is the target operand of one of the various Interlocked functions. Diese Operanden müssen über bestimmte zusätzliche Eigenschaften verfügen.Those operands must have specific additional properties.
_Write_guarded_by_(expr) Kommentiert eine Variable und gibt an, dass bei jeder Änderung der Variablen die Sperrenanzahl des Sperr Objekts, das durch benannt ist, mindestens expr eins ist.Annotates a variable and indicates that whenever the variable is modified, the lock count of the lock object that's named by expr is at least one.

Smart Lock-und RAII-AnmerkungenSmart Lock and RAII Annotations

Smart Locks wrappen in der Regel Native Sperren und verwalten ihre Lebensdauer.Smart locks typically wrap native locks and manage their lifetime. In der folgenden Tabelle sind Anmerkungen aufgelistet, die mit intelligenten Sperren und RAII-Codierungs Mustern mit Unterstützung für Semantik verwendet werden können move .The following table lists annotations that can be used with smart locks and RAII coding patterns with support for move semantics.

AnmerkungAnnotation BESCHREIBUNGDescription
_Analysis_assume_smart_lock_acquired_ Weist den Analyzer an, zu übernehmen, dass eine Smart Lock abgerufen wurde.Tells the analyzer to assume that a smart lock has been acquired. Diese Anmerkung erwartet einen verweissperrentyp als Parameter.This annotation expects a reference lock type as its parameter.
_Analysis_assume_smart_lock_released_ Weist den Analyzer an, zu übernehmen, dass eine Smart Lock freigegeben wurde.Tells the analyzer to assume that a smart lock has been released. Diese Anmerkung erwartet einen verweissperrentyp als Parameter.This annotation expects a reference lock type as its parameter.
_Moves_lock_(target, source) Beschreibt move constructor den Vorgang, der den Sperr Zustand von dem- source Objekt an den überträgt target .Describes move constructor operation which transfers lock state from the source object to the target. Der target wird als neu konstruiertes Objekt betrachtet, sodass jeder Zustand, den er hatte, verloren geht und durch den Zustand ersetzt wird source .The target is considered a newly constructed object, so any state it had before is lost and replaced by the source state. Der source wird auch auf einen sauberen Zustand zurückgesetzt, ohne dass eine Sperrenanzahl oder ein Alias Ziel vorhanden ist, aber Aliase, die darauf zeigen, bleiben unverändert.The source is also reset to a clean state with no lock counts or aliasing target, but aliases pointing to it remain unchanged.
_Replaces_lock_(target, source) Beschreibt die move assignment operator Semantik, bei der die Ziel Sperre freigegeben wird, bevor der Status aus der Quelle übertragen wird.Describes move assignment operator semantics where the target lock is released before transferring the state from the source. Dies kann als eine Kombination von _Moves_lock_(target, source) vorangestellt werden _Releases_lock_(target) .This can be regarded as a combination of _Moves_lock_(target, source) preceded by a _Releases_lock_(target).
_Swaps_locks_(left, right) Beschreibt das Standard swap Verhalten, bei dem davon ausgegangen wird, dass left -Objekte und right ihren Zustand austauschen.Describes the standard swap behavior which assumes that objects left and right exchange their state. Der ausgetauschte Status umfasst ggf. Sperr Anzahl und Aliasing-Ziel.The state exchanged includes lock count and aliasing target, if present. Aliase, die auf die left Objekte und zeigen, right bleiben unverändert.Aliases that point to the left and right objects remain unchanged.
_Detaches_lock_(detached, lock) Beschreibt ein Szenario, in dem ein Lock Wrapper Type die Trennung der enthaltenen Ressource zulässt.Describes a scenario in which a lock wrapper type allows dissociation with its contained resource. Dies ähnelt der Funktionsweise std::unique_ptr von mit dem internen Zeiger: Sie ermöglicht es Programmierern, den Zeiger zu extrahieren und den intelligenten Zeiger Container in einem sauberen Zustand zu belassen.This is similar to how std::unique_ptr works with its internal pointer: it allows programmers to extract the pointer and leave its smart pointer container in a clean state. Eine ähnliche Logik wird von unterstützt std::unique_lock und kann in benutzerdefinierten sperrwrappern implementiert werden.Similar logic is supported by std::unique_lock and can be implemented in custom lock wrappers. Die getrennte Sperre behält ihren Zustand (sofern vorhanden) bei, während der Wrapper zurückgesetzt wird, sodass er keine Sperr Anzahl und kein Alias Ziel enthält, während seine eigenen Aliase beibehalten werden.The detached lock retains its state (lock count and aliasing target, if any), while the wrapper is reset to contain zero lock count and no aliasing target, while retaining its own aliases. Es gibt keinen Vorgang für Sperr Zählungen (freigeben und erwerben).There's no operation on lock counts (releasing and acquiring). Diese Anmerkung verhält sich genau so _Moves_lock_ , als ob das getrennte Argument return nicht sein sollte this .This annotation behaves exactly as _Moves_lock_ except that the detached argument should be return rather than this.

Siehe auchSee also