Structures de données de synchronisation
Le runtime d’accès concurrentiel fournit plusieurs structures de données qui vous permettent de synchroniser l’accès aux données partagées à partir de plusieurs threads. Ces structures de données sont utiles lorsque vous avez partagé des données que vous modifiez rarement. Un objet de synchronisation, par exemple, une section critique, entraîne l’attente d’autres threads jusqu’à ce que la ressource partagée soit disponible. Par conséquent, si vous utilisez un tel objet pour synchroniser l’accès aux données fréquemment utilisées, vous pouvez perdre l’extensibilité dans votre application. La bibliothèque de modèles parallèles (PPL) fournit la classe concurrency ::combinable , qui vous permet de partager une ressource entre plusieurs threads ou tâches sans avoir besoin de synchronisation. Pour plus d’informations sur la combinable
classe, consultez Conteneurs et objets parallèles.
Sections
Cette rubrique décrit en détail les types de blocs de messages asynchrones suivants :
critical_section
La classe concurrency ::critical_section représente un objet d’exclusion mutuelle coopérative qui se traduit par d’autres tâches au lieu de les préempter. Les sections critiques sont utiles lorsque plusieurs threads nécessitent un accès exclusif en lecture et en écriture aux données partagées.
La critical_section
classe n’est pas réentrante. La méthode concurrency ::critical_section ::lock lève une exception de type concurrency ::improper_lock si elle est appelée par le thread qui possède déjà le verrou.
Méthodes et fonctionnalités
Le tableau suivant présente les méthodes importantes définies par la critical_section
classe.
Méthode | Description |
---|---|
lock | Acquiert la section critique. Le contexte appelant bloque jusqu’à ce qu’il acquiert le verrou. |
try_lock | Tente d’acquérir la section critique, mais ne bloque pas. |
unlock | Libère la section critique. |
[Haut]
reader_writer_lock
La classe concurrency ::reader_writer_lock fournit des opérations de lecture/écriture thread-safe aux données partagées. Utilisez des verrous de lecteur/enregistreur lorsque plusieurs threads nécessitent un accès en lecture simultané à une ressource partagée, mais qu’ils écrivent rarement dans cette ressource partagée. Cette classe ne donne qu’un seul accès en écriture de thread à un objet à tout moment.
La reader_writer_lock
classe peut fonctionner mieux que la critical_section
classe, car un objet acquiert un critical_section
accès exclusif à une ressource partagée, ce qui empêche l’accès en lecture simultané.
Comme la critical_section
classe, la reader_writer_lock
classe représente un objet d’exclusion mutuelle coopérative qui donne à d’autres tâches au lieu de les préempter.
Lorsqu’un thread qui doit écrire dans une ressource partagée acquiert un verrou lecteur/enregistreur, d’autres threads qui doivent également accéder à la ressource sont bloqués jusqu’à ce que l’enregistreur libère le verrou. La reader_writer_lock
classe est un exemple de verrou de préférence d’écriture, qui est un verrou qui débloque les enregistreurs en attente avant de débloquer les lecteurs en attente.
Comme la critical_section
classe, la reader_writer_lock
classe n’est pas réentrante. Les méthodes concurrency ::reader_writer_lock ::lock et concurrency ::reader_writer_lock ::lock_read lèvent une exception de type improper_lock
si elles sont appelées par un thread qui possède déjà le verrou.
Remarque
Étant donné que la reader_writer_lock
classe n’est pas réentrante, vous ne pouvez pas mettre à niveau un verrou en lecture seule vers un verrou lecteur/enregistreur ou rétrograder un verrou lecteur/enregistreur vers un verrou en lecture seule. L’exécution de l’une de ces opérations produit un comportement non spécifié.
Méthodes et fonctionnalités
Le tableau suivant présente les méthodes importantes définies par la reader_writer_lock
classe.
Méthode | Description |
---|---|
lock | Acquiert l’accès en lecture/écriture au verrou. |
try_lock | Tente d’acquérir l’accès en lecture/écriture au verrou, mais ne bloque pas. |
lock_read | Acquiert l’accès en lecture seule au verrou. |
try_lock_read | Tente d’acquérir un accès en lecture seule au verrou, mais ne bloque pas. |
unlock | Libère le verrou. |
[Haut]
scoped_lock et scoped_lock_read
Les critical_section
classes et reader_writer_lock
les classes fournissent des classes d’assistance imbriquées qui simplifient la façon dont vous travaillez avec des objets d’exclusion mutuelle. Ces classes d’assistance sont appelées verrous délimités.
La critical_section
classe contient la classe concurrency ::critical_section ::scoped_lock . Le constructeur acquiert l’accès à l’objet fourni critical_section
; le destructeur libère l’accès à cet objet. La reader_writer_lock
classe contient la classe concurrency ::reader_writer_lock ::scoped_lock, qui ressemblecritical_section::scoped_lock
, sauf qu’elle gère l’accès en écriture à l’objet fournireader_writer_lock
. La reader_writer_lock
classe contient également la classe concurrency ::reader_writer_lock ::scoped_lock_read . Cette classe gère l’accès en lecture à l’objet fourni reader_writer_lock
.
Les verrous délimités offrent plusieurs avantages lorsque vous utilisez et reader_writer_lock
utilisez critical_section
des objets manuellement. En règle générale, vous allouez un verrou délimité sur la pile. Un verrou délimité libère automatiquement l’accès à son objet d’exclusion mutuelle lorsqu’il est détruit ; par conséquent, vous ne déverrouillez pas manuellement l’objet sous-jacent. Cela est utile lorsqu’une fonction contient plusieurs return
instructions. Les verrous délimités peuvent également vous aider à écrire du code sans risque d’exception. Lorsqu’une throw
instruction entraîne le déroulement de la pile, le destructeur pour tout verrou d’étendue active est appelé, et par conséquent, l’objet d’exclusion mutuelle est toujours libéré correctement.
Remarque
Lorsque vous utilisez les critical_section::scoped_lock
classes , reader_writer_lock::scoped_lock
et reader_writer_lock::scoped_lock_read
que vous n’utilisez pas manuellement l’accès à l’objet d’exclusion mutuelle sous-jacent. Cela peut placer le runtime dans un état non valide.
événement
La classe concurrency ::event représente un objet de synchronisation dont l’état peut être signalé ou non signalé. Contrairement aux objets de synchronisation, tels que les sections critiques, dont l’objectif est de protéger l’accès aux données partagées, les événements synchronisent le flux d’exécution.
La event
classe est utile lorsqu’une tâche a terminé le travail d’une autre tâche. Par exemple, une tâche peut signaler à une autre tâche qu’elle a lu des données à partir d’une connexion réseau ou d’un fichier.
Méthodes et fonctionnalités
Le tableau suivant présente plusieurs des méthodes importantes définies par la event
classe.
Méthode | Description |
---|---|
Attendre | Attend que l’événement soit signalé. |
set | Définit l’événement à l’état signalé. |
reset | Définit l’événement à l’état non signalé. |
wait_for_multiple | Attend que plusieurs événements soient signalés. |
Exemple
Pour obtenir un exemple montrant comment utiliser la event
classe, consultez Comparaison des structures de données de synchronisation à l’API Windows.
[Haut]
Sections connexes
Comparaison des structures de données de synchronisation avec l’API Windows
Compare le comportement des structures de données de synchronisation à celles fournies par l’API Windows.
Concurrency Runtime
Décrit le runtime d'accès concurrentiel, qui simplifie la programmation parallèle, et contient des liens vers les rubriques connexes.