Priorités de planification

Les threads sont planifiés pour s’exécuter en fonction de leur priorité de planification. Une priorité de planification est affectée à chaque thread. Les niveaux de priorité vont de zéro (priorité la plus faible) à 31 (priorité la plus élevée). Seul le thread de page zéro peut avoir une priorité de zéro. (Le thread de page zéro est un thread système chargé de mettre à zéro toutes les pages libres lorsqu’aucun autre thread n’a besoin de s’exécuter.)

Le système traite tous les threads ayant la même priorité comme égaux. Le système assigne des tranches de temps de façon tourniquet (round robin) à tous les threads ayant la priorité la plus élevée. Si aucun de ces threads n’est prêt à être exécuté, le système affecte des tranches de temps de façon tourniquet à tous les threads ayant la priorité la plus élevée suivante. Si un thread de priorité plus élevée devient disponible pour l’exécution, le système cesse d’exécuter le thread de priorité inférieure (sans lui permettre d’utiliser son segment de temps) et affecte une tranche à temps complet au thread de priorité supérieure. Pour plus d’informations, consultez Commutateurs de contexte.

La priorité de chaque thread est déterminée par les critères suivants :

  • Classe de priorité de son processus
  • Niveau de priorité du thread dans la classe de priorité de son processus

La classe de priorité et le niveau de priorité sont combinés pour former la priorité de base d’un thread. Pour plus d’informations sur la priorité dynamique d’un thread, consultez Priority Boosts.

Classe Priority

Chaque processus appartient à l’une des classes de priorité suivantes :

IDLE_PRIORITY_CLASS
BELOW_NORMAL_PRIORITY_CLASS
NORMAL_PRIORITY_CLASS
ABOVE_NORMAL_PRIORITY_CLASS
HIGH_PRIORITY_CLASS
REALTIME_PRIORITY_CLASS

Par défaut, la classe de priorité d’un processus est NORMAL_PRIORITY_CLASS. Utilisez la fonction CreateProcess pour spécifier la classe de priorité d’un processus enfant lorsque vous le créez. Si le processus appelant est IDLE_PRIORITY_CLASS ou BELOW_NORMAL_PRIORITY_CLASS, le nouveau processus héritera de cette classe. Utilisez la fonction GetPriorityClass pour déterminer la classe de priorité actuelle d’un processus et la fonction SetPriorityClass pour modifier la classe de priorité d’un processus.

Les processus qui surveillent le système, tels que les filtres d’écran ou les applications qui mettent régulièrement à jour un affichage, doivent utiliser IDLE_PRIORITY_CLASS. Cela empêche les threads de ce processus, qui n’ont pas une priorité élevée, d’interférer avec les threads de priorité plus élevée.

Utilisez HIGH_PRIORITY_CLASS avec précaution. Si un thread s’exécute au niveau de priorité le plus élevé pendant des périodes prolongées, les autres threads du système n’obtiennent pas de temps processeur. Si plusieurs threads sont définis à priorité élevée en même temps, les threads perdent leur efficacité. La classe de priorité élevée doit être réservée aux threads qui doivent répondre aux événements temporels critiques. Si votre application effectue une tâche qui nécessite la classe de priorité élevée alors que les autres tâches sont normales, utilisez SetPriorityClass pour augmenter temporairement la classe de priorité de l’application ; réduisez-la ensuite une fois la tâche critique terminée. Une autre stratégie consiste à créer un processus de haute priorité dans lequel tous ses threads sont bloqués la plupart du temps, en réveillant les threads uniquement lorsque des tâches critiques sont nécessaires. Le point important est qu’un thread de priorité élevée doit s’exécuter pendant une courte période, et uniquement lorsqu’il a un travail critique à effectuer.

Vous ne devez presque jamais utiliser REALTIME_PRIORITY_CLASS, car cela interrompt les threads système qui gèrent l’entrée de la souris, l’entrée au clavier et le vidage du disque en arrière-plan. Cette classe peut convenir aux applications qui « parlent » directement au matériel ou qui effectuent de brèves tâches qui doivent avoir des interruptions limitées.

Niveau de priorité

Voici les niveaux de priorité au sein de chaque classe de priorité :

THREAD_PRIORITY_IDLE
THREAD_PRIORITY_LOWEST
THREAD_PRIORITY_BELOW_NORMAL
THREAD_PRIORITY_NORMAL
THREAD_PRIORITY_ABOVE_NORMAL
THREAD_PRIORITY_HIGHEST
THREAD_PRIORITY_TIME_CRITICAL

Tous les threads sont créés à l’aide de THREAD_PRIORITY_NORMAL. Cela signifie que la priorité du thread est la même que la classe de priorité de processus. Après avoir créé un thread, utilisez la fonction SetThreadPriority pour ajuster sa priorité par rapport aux autres threads du processus.

Une stratégie classique consiste à utiliser THREAD_PRIORITY_ABOVE_NORMAL ou THREAD_PRIORITY_HIGHEST pour le thread d’entrée du processus, afin de s’assurer que l’application est réactive à l’utilisateur. Les threads d’arrière-plan, en particulier ceux qui nécessitent beaucoup de processeur, peuvent être définis sur THREAD_PRIORITY_BELOW_NORMAL ou THREAD_PRIORITY_LOWEST, afin de garantir qu’ils peuvent être préemptés si nécessaire. Toutefois, si vous avez un thread en attente d’un autre thread avec une priorité inférieure pour effectuer une tâche, veillez à bloquer l’exécution du thread de priorité élevée en attente. Pour ce faire, utilisez une fonction d’attente, une section critique ou la fonction Sleep , SleepEx ou SwitchToThread . Cela est préférable au fait que le thread exécute une boucle. Sinon, le processus peut devenir bloqué, car le thread avec une priorité inférieure n’est jamais planifié.

Pour déterminer le niveau de priorité actuel d’un thread, utilisez la fonction GetThreadPriority .

Priorité de base

La classe de priorité de processus et le niveau de priorité de thread sont combinés pour former la priorité de base de chaque thread.

Le tableau suivant montre la priorité de base pour les combinaisons de classe de priorité de processus et de valeur de priorité de thread.

Classe de priorité de processus Niveau de priorité du thread Priorité de base
IDLE_PRIORITY_CLASS THREAD_PRIORITY_IDLE 1
THREAD_PRIORITY_LOWEST 2
THREAD_PRIORITY_BELOW_NORMAL 3
THREAD_PRIORITY_NORMAL 4
THREAD_PRIORITY_ABOVE_NORMAL 5
THREAD_PRIORITY_HIGHEST 6
THREAD_PRIORITY_TIME_CRITICAL 15
BELOW_NORMAL_PRIORITY_CLASS THREAD_PRIORITY_IDLE 1
THREAD_PRIORITY_LOWEST 4
THREAD_PRIORITY_BELOW_NORMAL 5
THREAD_PRIORITY_NORMAL 6
THREAD_PRIORITY_ABOVE_NORMAL 7
THREAD_PRIORITY_HIGHEST 8
THREAD_PRIORITY_TIME_CRITICAL 15
NORMAL_PRIORITY_CLASS THREAD_PRIORITY_IDLE 1
THREAD_PRIORITY_LOWEST 6
THREAD_PRIORITY_BELOW_NORMAL 7
THREAD_PRIORITY_NORMAL 8
THREAD_PRIORITY_ABOVE_NORMAL 9
THREAD_PRIORITY_HIGHEST 10
THREAD_PRIORITY_TIME_CRITICAL 15
ABOVE_NORMAL_PRIORITY_CLASS THREAD_PRIORITY_IDLE 1
THREAD_PRIORITY_LOWEST 8
THREAD_PRIORITY_BELOW_NORMAL 9
THREAD_PRIORITY_NORMAL 10
THREAD_PRIORITY_ABOVE_NORMAL 11
THREAD_PRIORITY_HIGHEST 12
THREAD_PRIORITY_TIME_CRITICAL 15
HIGH_PRIORITY_CLASS THREAD_PRIORITY_IDLE 1
THREAD_PRIORITY_LOWEST 11
THREAD_PRIORITY_BELOW_NORMAL 12
THREAD_PRIORITY_NORMAL 13
THREAD_PRIORITY_ABOVE_NORMAL 14
THREAD_PRIORITY_HIGHEST 15
THREAD_PRIORITY_TIME_CRITICAL 15
REALTIME_PRIORITY_CLASS THREAD_PRIORITY_IDLE 16
THREAD_PRIORITY_LOWEST 22
THREAD_PRIORITY_BELOW_NORMAL 23
THREAD_PRIORITY_NORMAL 24
THREAD_PRIORITY_ABOVE_NORMAL 25
THREAD_PRIORITY_HIGHEST 26
THREAD_PRIORITY_TIME_CRITICAL 31