Annotation du comportement de verrouillageAnnotating Locking Behavior

Pour éviter les bogues d’accès concurrentiel dans votre programme multithread, suivez toujours une discipline de verrouillage appropriée et utilisez les annotations SAL.To avoid concurrency bugs in your multithreaded program, always follow an appropriate locking discipline and use SAL annotations.

Il est notoirement difficile de reproduire, de diagnostiquer et de déboguer des bogues d'accès concurrentiel en raison de leur nature non déterministe.Concurrency bugs are notoriously hard to reproduce, diagnose, and debug because they are non-deterministic. Comprendre les entrelacements de thread est au mieux difficile, et devient impossible lorsque vous concevez un corps de code qui compte plus que quelques threads.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. Par conséquent, il est recommandé de suivre une règle de verrouillage dans vos programmes multithread.Therefore, it's good practice to follow a locking discipline in your multithreaded programs. Par exemple, obéir à un ordre de verrou tout en obtenant plusieurs verrous permet d'éviter des interblocages, et acquérir le verrou de garde approprié avant d'accéder à une ressource partagée permet d'éviter des conditions de concurrence.For 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.

Malheureusement, ces règles de verrouillage apparemment simples peuvent être étonnamment difficiles à suivre en pratique.Unfortunately, seemingly simple locking rules can be surprisingly hard to follow in practice. Une restriction fondamentale dans les langages de programmation et les compilateurs d’aujourd'hui est qu’ils ne gèrent pas directement la spécification et l’analyse des conditions de concurrence.A fundamental limitation in today's programming languages and compilers is that they do not directly support the specification and analysis of concurrency requirements. Les programmeurs doivent s'appuyer sur les commentaires de code informels pour exprimer leurs intentions sur la façon dont ils utilisent des verrous.Programmers have to rely on informal code comments to express their intentions about how they use locks.

Les annotations SAL d'accès concurrentiel sont conçues pour vous aider à spécifier les effets secondaires du verrouillage, le responsable du verrouillage, la tutelle de données, la hiérarchie d'ordre de verrou et d'autres comportements de verrouillage prévus.Concurrency SAL annotations are designed to help you specify locking side effects, locking responsibility, data guardianship, lock order hierarchy, and other expected locking behavior. En transformant des règles implicites en règles explicites, les annotations d'accès concurrence SAL vous permettent de documenter la façon dont votre code utilise des règles de verrouillage.By making implicit rules explicit, SAL concurrency annotations provide a consistent way for you to document how your code uses locking rules. Les annotations d’accès concurrentiel améliorent également la capacité des outils d’analyse du code à rechercher des conditions de concurrence, des interblocages, des opérations de synchronisation incompatibles et d’autres erreurs subtiles d’accès concurrentiel.Concurrency annotations also enhance the ability of code analysis tools to find race conditions, deadlocks, mismatched synchronization operations, and other subtle concurrency errors.

Indications généralesGeneral Guidelines

Les annotations permettent aux programmeurs de déclarer les contrats sous-entendus par les définitions de fonction entre les implémentations (appelés) et les clients (appelants) et d'exprimer les invariants et d'autres propriétés du programme qui peuvent améliorer davantage l'analyse.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 prend en charge de nombreux types de primitives de verrouillage, tels que les sections critiques, les mutex, les verrous de rotation et d'autres objets de ressource.SAL supports many different kinds of locking primitives—for example, critical sections, mutexes, spin locks, and other resource objects. Plusieurs annotations d’accès concurrentiel prennent une expression de verrouillage en tant que paramètre.Many concurrency annotations take a lock expression as a parameter. Par convention, un verrou est représenté par l’expression de chemin d’accès de l’objet verrou sous-jacent.By convention, a lock is denoted by the path expression of the underlying lock object.

Quelques règles de propriété concernant les threads à garder en tête :Some thread ownership rules to keep in mind:

  • Les verrous de rotation sont des verrous non numérotés qui ont une propriété de thread précise.Spin locks are uncounted locks that have clear thread ownership.

  • Les mutex et les sections critiques sont des verrous numérotés qui ont une propriété de thread précise.Mutexes and critical sections are counted locks that have clear thread ownership.

  • Les sémaphores et les événements sont des verrous numérotés qui n'ont pas de propriété de thread précise.Semaphores and events are counted locks that do not have clear thread ownership.

Annotations de verrouillageLocking Annotations

Le tableau suivant répertorie les annotations de verrouillage.The following table lists the locking annotations.

AnnotationAnnotation DescriptionDescription
_Acquires_exclusive_lock_(expr) Annote une fonction et indique qu'à l'état postérieur la fonction incrémente d'une unité le nombre de verrous exclusifs de l'objet verrou nommé par 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) Annote une fonction et indique qu'à l'état postérieur la fonction incrémente d'une unité le nombre de verrous de l'objet verrou nommé par 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) Le verrou nommé par expr est acquis.The lock that's named by expr is acquired. Une erreur est signalée si le verrou est déjà détenu.An error is reported if the lock is already held.
_Acquires_shared_lock_(expr) Annote une fonction et indique qu'à l'état postérieur la fonction incrémente d'une unité le nombre de verrous partagés de l'objet verrou nommé par 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) Instruction qui déclare le symbole name comme un niveau de verrou afin qu'il puisse être utilisé dans les annotations _Has_Lock_level_ et _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) Annote un objet pour affiner les informations de type d’un objet de ressource.Annotates any object to refine the type information of a resource object. Parfois, un type commun est utilisé pour les différents types de ressources et le type surchargé n’est pas suffisant pour distinguer les exigences sémantiques entre les différentes ressources.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. Voici la liste des paramètres kind prédéfinis :Here's a list of pre-defined kind parameters:

_Lock_kind_mutex_
ID de type de verrou de mutex.Lock kind ID for mutexes.

_Lock_kind_event_
ID de type de verrouillage pour les événements.Lock kind ID for events.

_Lock_kind_semaphore_
ID de type de verrouillage pour les sémaphores.Lock kind ID for semaphores.

_Lock_kind_spin_lock_
ID de type de verrouillage pour les verrous de rotation.Lock kind ID for spin locks.

_Lock_kind_critical_section_
ID de type de verrouillage pour les sections critiques.Lock kind ID for critical sections.
_Has_lock_level_(name) Annote un objet verrou, en lui donnant le niveau de verrou de name.Annotates a lock object and gives it the lock level of name.
_Lock_level_order_(name1, name2) Une instruction qui donne le verrou de classement entre name1 et name2.A statement that gives the lock ordering between name1 and name2.
_Post_same_lock_(expr1, expr2) Annote une fonction et indique qu'à l'état postérieur les deux verrous, expr1 et expr2, sont traités comme s'ils étaient le même objet verrou.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) Annote une fonction et indique qu'à l'état postérieur la fonction décrémente d'une unité le nombre de verrous exclusifs de l'objet verrou nommé par 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) Annote une fonction et indique qu'à l'état postérieur la fonction décrémente d'une unité le nombre de verrous de l'objet verrou nommé par 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) Le verrou nommé par expr est libéré.The lock that's named by expr is released. Une erreur est signalée si le verrou n'est pas actuellement détenu.An error is reported if the lock is not currently held.
_Releases_shared_lock_(expr) Annote une fonction et indique qu'à l'état postérieur la fonction décrémente d'une unité le nombre de verrous partagés de l'objet verrou nommé par 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) Annote une fonction et indique qu'à l'état antérieur le nombre de verrous de l'objet nommé par expr est d'au moins un.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) Annote une fonction et indique qu'à l'état antérieur le nombre de verrous de l'objet nommé par expr est zéro.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_ Annote une fonction et indique que le nombre de verrous de tous les verrous connus par le vérificateur est égal à zéro.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) Annote une fonction et indique qu'à l'état antérieur le nombre de verrous partagés de l'objet nommé par expr est d'au moins un.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) Annote une fonction et indique qu'à l'état antérieur le nombre de verrous exclusifs de l'objet nommé par expr est d'au moins un.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.

Intrinsèques SAL pour les objets de verrouillage non exposésSAL Intrinsics For Unexposed Locking Objects

Certains objets de verrouillage ne sont pas exposées par l’implémentation des fonctions de verrouillage associées.Certain lock objects are not exposed by the implementation of the associated locking functions. Le tableau suivant répertorie les variables intrinsèques SAL qui autorisent les annotations sur les fonctions qui s'exécutent sur ces objets verrous non exposés.The following table lists SAL intrinsic variables that enable annotations on functions that operate on those unexposed lock objects.

AnnotationAnnotation DescriptionDescription
_Global_cancel_spin_lock_ Décrit le verrou d'annulation de rotation.Describes the cancel spin lock.
_Global_critical_region_ Décrit la zone critique.Describes the critical region.
_Global_interlock_ Décrit les opérations verrouillées.Describes interlocked operations.
_Global_priority_region_ Décrit la zone de priorité.Describes the priority region.

Annotations d’accès aux données partagéesShared Data Access Annotations

Le tableau suivant répertorie les annotations à utiliser avec l'accès aux données partagées.The following table lists the annotations for shared data access.

AnnotationAnnotation DescriptionDescription
_Guarded_by_(expr) Annote une variable et indique qu'à chaque accès à la variable, le nombre de verrous de l'objet verrou nommé par expr est d'au moins un.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_ Annote une variable et équivaut à _Guarded_by_(_Global_interlock_).Annotates a variable and is equivalent to _Guarded_by_(_Global_interlock_).
_Interlocked_operand_ Le paramètre de fonction annoté est l’opérande de la cible de l’une des diverses fonctions Interlocked.The annotated function parameter is the target operand of one of the various Interlocked functions. Les opérandes doivent avoir des propriétés supplémentaires spécifiques.Those operands must have specific additional properties.
_Write_guarded_by_(expr) Annote une variable et indique qu'à chaque modification de la variable, le nombre de verrous de l'objet verrou nommé par expr est d'au moins un.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.

Voir aussiSee Also

Utilisation d’Annotations SAL pour réduire les défauts du Code C/C++ Using SAL Annotations to Reduce C/C++ Code Defects
Présentation de SAL Understanding SAL
Annotation de paramètres de fonction et valeurs de retour Annotating Function Parameters and Return Values
Annotation du comportement de la fonction Annotating Function Behavior
Les structures et Classes d’annotation Annotating Structs and Classes
Spécification de quand et où une Annotation est applicable Specifying When and Where an Annotation Applies
Fonctions intrinsèques Intrinsic Functions
Meilleures pratiques et exemples Best Practices and Examples
Blog de l’équipe analyse du codeCode Analysis Team Blog