Priorità di pianificazione
I thread vengono pianificati in base alla priorità di pianificazione. Ogni thread viene assegnato a una priorità di pianificazione. I livelli di priorità sono compresi tra zero (priorità più bassa) e 31 (priorità più alta). Solo il thread a pagina zero può avere una priorità pari a zero. Il thread zero-page è un thread di sistema responsabile dell'zero delle pagine gratuite quando non sono presenti altri thread che devono essere eseguiti.
Il sistema tratta tutti i thread con la stessa priorità di uguale. Il sistema assegna sezioni temporali in modo round robin a tutti i thread con la priorità più alta. Se nessuno di questi thread è pronto per l'esecuzione, il sistema assegna sezioni temporali in modo round robin a tutti i thread con la priorità più alta. Se un thread con priorità superiore diventa disponibile per l'esecuzione, il sistema smette di eseguire il thread con priorità inferiore (senza consentire il completamento della sezione temporale) e assegna una sezione full-time al thread con priorità più alta. Per altre informazioni, vedere Commutatori di contesto.
La priorità di ogni thread è determinata dai criteri seguenti:
- Classe di priorità del relativo processo
- Livello di priorità del thread all'interno della classe priorità del relativo processo
La classe di priorità e il livello di priorità vengono combinati per formare la priorità di base di un thread. Per informazioni sulla priorità dinamica di un thread, vedere Boosts (Incrementi di priorità).
Classe Priority
Ogni processo appartiene a una delle classi di priorità seguenti:
- IDLE_PRIORITY_CLASS
BELOW_NORMAL_PRIORITY_CLASS
NORMAL_PRIORITY_CLASS
ABOVE_NORMAL_PRIORITY_CLASS
HIGH_PRIORITY_CLASS
REALTIME_PRIORITY_CLASS
Per impostazione predefinita, la classe priorità di un processo è NORMAL_PRIORITY_CLASS. Usare la funzione CreateProcess per specificare la classe priorità di un processo figlio quando viene creata. Se il processo chiamante è IDLE_PRIORITY_CLASS o BELOW_NORMAL_PRIORITY_CLASS, il nuovo processo erediterà questa classe. Utilizzare la funzione GetPriorityClass per determinare la classe di priorità corrente di un processo e la funzione SetPriorityClass per modificare la classe di priorità di un processo.
I processi che monitorano il sistema, ad esempio gli screen saver o le applicazioni che aggiornano periodicamente una visualizzazione, devono usare IDLE_PRIORITY_CLASS. Ciò impedisce ai thread di questo processo, che non hanno priorità elevata, di interferire con thread con priorità superiore.
Usare HIGH_PRIORITY_CLASS con cura. Se un thread viene eseguito al livello di priorità più alto per periodi estesi, gli altri thread nel sistema non otterranno il tempo di processore. Se diversi thread vengono impostati contemporaneamente con priorità elevata, i thread perderanno l'efficacia. La classe ad alta priorità deve essere riservata ai thread che devono rispondere agli eventi time-critical. Se l'applicazione esegue un'attività che richiede la classe ad alta priorità mentre il resto delle attività è normale, usare SetPriorityClass per aumentare temporaneamente la classe di priorità dell'applicazione; quindi ridurla dopo il completamento dell'attività critica. Un'altra strategia consiste nel creare un processo con priorità elevata che ha tutti i thread bloccati la maggior parte del tempo, risvegliando i thread solo quando sono necessarie attività critiche. Il punto importante è che un thread con priorità elevata deve essere eseguito per un breve periodo di tempo e solo quando ha un lavoro critico per l'esecuzione.
Non usare quasi mai REALTIME_PRIORITY_CLASS, perché questo interrompe i thread di sistema che gestiscono l'input del mouse, l'input della tastiera e lo scaricamento del disco in background. Questa classe può essere appropriata per le applicazioni che "parlano" direttamente all'hardware o che eseguono brevi attività che devono avere interruzioni limitate.
Livello di priorità
Di seguito sono riportati i livelli di priorità all'interno di ogni classe prioritaria:
- THREAD_PRIORITY_IDLE
THREAD_PRIORITY_LOWEST
THREAD_PRIORITY_BELOW_NORMAL
THREAD_PRIORITY_NORMAL
THREAD_PRIORITY_ABOVE_NORMAL
THREAD_PRIORITY_HIGHEST
THREAD_PRIORITY_TIME_CRITICAL
Tutti i thread vengono creati usando THREAD_PRIORITY_NORMAL. Ciò significa che la priorità del thread è uguale alla classe di priorità del processo. Dopo aver creato un thread, usare la funzione SetThreadPriority per regolarne la priorità rispetto ad altri thread nel processo.
Una strategia tipica consiste nell'usare THREAD_PRIORITY_ABOVE_NORMAL o THREAD_PRIORITY_HIGHEST per il thread di input del processo, per assicurarsi che l'applicazione sia reattiva all'utente. I thread in background, in particolare quelli che sono a elevato utilizzo del processore, possono essere impostati su THREAD_PRIORITY_BELOW_NORMAL o THREAD_PRIORITY_LOWEST, per assicurarsi che possano essere preceduti quando necessario. Tuttavia, se si ha un thread in attesa di un altro thread con una priorità inferiore per completare un'attività, assicurarsi di bloccare l'esecuzione del thread ad alta priorità in attesa. A tale scopo, usare una funzione di attesa, una sezione criticao la funzione Sleep, SleepEx o SwitchToThread . È preferibile avere il thread eseguito un ciclo. In caso contrario, il processo può diventare deadlock, perché il thread con priorità inferiore non è mai pianificato.
Per determinare il livello di priorità corrente di un thread, usare la funzione GetThreadPriority .
Priorità di base
La classe di priorità del processo e il livello di priorità del thread vengono combinati per formare la priorità di base di ogni thread.
Nella tabella seguente viene illustrata la priorità di base per le combinazioni di valori di priorità del processo e priorità thread.
Classe priorità processo | Livello di priorità del thread | Priorità di 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 |