Planification des priorités

Les threads sont planifiés pour s’exécuter en fonction de leur priorité de planification. Chaque thread est affecté à une priorité de planification. Les niveaux de priorité varient de zéro (priorité la plus basse) à 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 zéro pages libres lorsqu’il n’y a pas d’autres threads qui doivent s’exécuter.)

Le système traite tous les threads avec la même priorité que celle égale. Le système affecte des tranches de temps d’une manière tourniquet à tous les threads avec la priorité la plus élevée. Si aucun de ces threads n’est prêt à s’exécuter, le système affecte des tranches de temps d’une manière tourniquet à tous les threads avec la priorité la plus élevée suivante. Si un thread de priorité supérieure devient disponible pour s’exécuter, le système cesse d’exécuter le thread de priorité inférieure (sans l’autoriser à terminer à l’aide de sa tranche de temps) et affecte une tranche à temps plein 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 Boosts de priorité.

Classe De priorité

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érite 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 enregistreurs 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 de priorité élevée, d’interférer avec les threads de priorité supérieure.

Utilisez HIGH_PRIORITY_CLASS avec soin. Si un thread s’exécute au niveau de priorité le plus élevé pendant des périodes prolongées, d’autres threads du système ne reçoivent pas de temps processeur. Si plusieurs threads sont définis en même temps à priorité élevée, les threads perdent leur efficacité. La classe à priorité élevée doit être réservée aux threads qui doivent répondre aux événements critiques au moment. Si votre application effectue une tâche qui nécessite la classe de priorité élevée alors que le reste de ses tâches est une priorité normale, utilisez SetPriorityClass pour élever 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 à priorité élevée qui a tous ses threads bloqués la plupart du temps, les threads d’éveil uniquement lorsque des tâches critiques sont nécessaires. Le point important est qu’un thread à priorité élevée doit s’exécuter pendant une courte période, et uniquement lorsqu’il dispose d’un travail critique pour l’exécution.

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 clavier et le vidage du disque en arrière-plan. Cette classe peut être appropriée pour les 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é dans 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é de thread est identique à 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 sont gourmands en processeur, peuvent être définis sur THREAD_PRIORITY_BELOW_NORMAL ou THREAD_PRIORITY_LOWEST, pour s’assurer 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 haute priorité 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 à l’exécution d’une boucle par le thread. 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 classes 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