Contextes
Ce document décrit le rôle des contextes dans le runtime d’accès concurrentiel. Un thread attaché à un planificateur est appelé contexte d’exécution, ou simplement contexte. La fonction concurrency ::wait et la classe concurrency ::Context vous permettent de contrôler le comportement des contextes. Utilisez la wait
fonction pour suspendre le contexte actuel pendant une heure spécifiée. Utilisez la Context
classe lorsque vous avez besoin d’un contrôle supplémentaire sur le moment où les contextes bloquent, débloquent et produisent, ou lorsque vous souhaitez sursubcrire le contexte actuel.
Conseil
Le runtime d'accès concurrentiel fournit un planificateur par défaut, et vous n'êtes donc pas obligé d'en créer un dans votre application. Étant donné que le planificateur de tâches vous aide à affiner les performances de vos applications, nous vous recommandons de commencer par la bibliothèque de modèles parallèles (PPL) ou la bibliothèque d’agents asynchrones si vous débutez avec le runtime d’accès concurrentiel.
Fonction d’attente
La fonction concurrency ::wait génère de manière coopérative l’exécution du contexte actuel pour un nombre spécifié de millisecondes. Le runtime utilise le temps de rendement pour effectuer d’autres tâches. Une fois le temps spécifié écoulé, le runtime replanifie le contexte d’exécution. Par conséquent, la wait
fonction peut suspendre le contexte actuel plus long que la valeur fournie pour le milliseconds
paramètre.
Le passage de 0 (zéro) pour le milliseconds
paramètre entraîne la suspension du contexte actuel jusqu’à ce que tous les autres contextes actifs soient donnés la possibilité d’effectuer un travail. Cela vous permet de générer une tâche à toutes les autres tâches actives.
Exemple
Pour obtenir un exemple qui utilise la wait
fonction pour générer le contexte actuel, et ainsi autoriser l’exécution d’autres contextes, consultez Guide pratique pour utiliser des groupes de planification pour influencer l’ordre d’exécution.
Classe de contexte
La classe concurrency ::Context fournit une abstraction de programmation pour un contexte d’exécution et offre deux fonctionnalités importantes : la possibilité de bloquer, débloquer et générer le contexte actuel et la possibilité de sursubcrire le contexte actuel.
Blocage coopératif
La Context
classe vous permet de bloquer ou de générer le contexte d’exécution actuel. Le blocage ou le rendement est utile lorsque le contexte actuel ne peut pas continuer, car une ressource n’est pas disponible.
La méthode concurrency ::Context ::Block bloque le contexte actuel. Un contexte bloqué génère ses ressources de traitement afin que le runtime puisse effectuer d’autres tâches. La méthode concurrency ::Context ::Unblock débloque un contexte bloqué. La Context::Unblock
méthode doit être appelée à partir d’un contexte différent de celui qui a appelé Context::Block
. Le runtime lève l’accès concurrentiel ::context_self_unblock si un contexte tente de se débloquer lui-même.
Pour bloquer et débloquer un contexte, vous appelez généralement concurrency ::Context ::CurrentContext pour récupérer un pointeur vers l’objet Context
associé au thread actuel et enregistrer le résultat. Vous appelez ensuite la Context::Block
méthode pour bloquer le contexte actuel. Plus tard, appelez Context::Unblock
à partir d’un contexte distinct pour débloquer le contexte bloqué.
Vous devez correspondre à chaque paire d’appels à Context::Block
et Context::Unblock
. Le runtime lève concurrency ::context_unblock_unbalanced lorsque la ou Context::Unblock
la Context::Block
méthode est appelée consécutivement sans appel correspondant à l’autre méthode. Toutefois, vous n’avez pas besoin d’appeler avant d’appeler Context::Block
Context::Unblock
. Par exemple, si un contexte appelle Context::Unblock
avant un autre contexte appelle Context::Block
le même contexte, ce contexte reste débloqué.
La méthode concurrency ::Context ::Yield génère l’exécution afin que le runtime puisse effectuer d’autres tâches, puis replanifier le contexte pour l’exécution. Lorsque vous appelez la Context::Block
méthode, le runtime ne replanifie pas le contexte.
Exemple
Pour obtenir un exemple qui utilise les méthodes et les méthodes pour implémenter une classe de sémaphore coopérative, consultez How to : Use the Context Class to Implement a Cooperative Smaphore.Context::Block
Context::Yield
Context::Unblock
Surabonnement
Le planificateur par défaut crée le même nombre de threads qu’il existe des threads matériels disponibles. Vous pouvez utiliser la sursubscription pour créer des threads supplémentaires pour un thread matériel donné.
Pour les opérations nécessitant beaucoup de ressources informatiques, la sursubscription n’est généralement pas mise à l’échelle, car elle introduit une surcharge supplémentaire. Toutefois, pour les tâches qui ont une grande latence, par exemple, la lecture de données à partir d’un disque ou d’une connexion réseau, la sursubscription peut améliorer l’efficacité globale de certaines applications.
Remarque
Activez la sursubscription uniquement à partir d’un thread créé par le runtime d’accès concurrentiel. Oversubscription n’a aucun effet lorsqu’il est appelé à partir d’un thread qui n’a pas été créé par le runtime (y compris le thread principal).
Pour activer la sursubscription dans le contexte actuel, appelez la méthode concurrency ::Context ::Oversubscribe avec le _BeginOversubscription
paramètre défini sur true
. Lorsque vous activez la sursubscription sur un thread créé par le runtime d’accès concurrentiel, le runtime crée un thread supplémentaire. Une fois toutes les tâches nécessitant une sursubscription terminées, appelez Context::Oversubscribe
avec le _BeginOversubscription
paramètre défini sur false
.
Vous pouvez activer le sursubscription plusieurs fois à partir du contexte actuel, mais vous devez le désactiver le même nombre de fois que vous l’activez. La sursubscription peut également être imbriquée ; autrement dit, une tâche créée par une autre tâche qui utilise le sursubscription peut également remplacer son contexte. Toutefois, si une tâche imbriquée et son parent appartiennent au même contexte, seul l’appel le plus externe provoque Context::Oversubscribe
la création d’un thread supplémentaire.
Remarque
Le runtime lève concurrency ::invalid_oversubscribe_operation si la sursubscription est désactivée avant son activation.
Exemple
Pour obtenir un exemple qui utilise le sursubscription pour décaler la latence provoquée par la lecture de données à partir d’une connexion réseau, consultez How to : Use Oversubscription to Offset Latency.
Voir aussi
Planificateur de tâches
Guide pratique pour utiliser des groupes de planification pour influencer l’ordre d’exécution
Guide pratique pour utiliser la classe Context pour implémenter un sémaphore coopératif
Guide pratique pour utiliser le surabonnement pour compenser la latence