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::BlockContext::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::BlockContext::YieldContext::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