Réponse courte
99 sera le gagnant pour la priorité en temps réel.
PR est le niveau de priorité (plage de -100 à 39). Plus le PR est bas, plus la priorité du processus sera élevée.
PR est calculé comme suit :
- pour les processus normaux :PR =20 + NI (NI est agréable et varie de -20 à 19)
- pour les processus en temps réel :PR =- 1 - real_time_priority(real_time_priority varie de 1 à 99)
Réponse longue
Il existe 2 types de processus, le normal et le temps réel Pour les normaux (et seulement pour ceux-là), nice s'applique comme suit :
Bien
L'échelle de "gentillesse" va de -20 à 19, alors que -20 est la priorité la plus élevée et 19 la priorité la plus basse. Le niveau de priorité est calculé comme suit :
PR =20 + NI
Où NI est le niveau agréable et PR est le niveau prioritaire. Donc, comme nous pouvons le voir, le -20 correspond en fait à 0, tandis que le 19 correspond à 39.
Par défaut, une valeur nice de programme est de 0 bit, il est possible pour un utilisateur root de lancer des programmes avec une valeur nice spécifiée en utilisant la commande suivante :
nice -n <nice_value> ./myProgram
Temps réel
On pourrait aller encore plus loin. La priorité nice est en fait utilisée pour les programmes utilisateur. Alors que la priorité globale UNIX/LINUX a une plage de 140 valeurs, la valeur nice permet au processus de mapper sur la dernière partie de la plage (de 100 à 139). Cette équation laisse inaccessibles les valeurs de 0 à 99 ce qui correspondra à un niveau PR négatif (de -100 à -1). Pour pouvoir accéder à ces valeurs, le processus doit être indiqué en "temps réel".
Il existe 5 politiques de planification dans un environnement LINUX qui peuvent être affichées avec la commande suivante :
chrt -m
Ce qui affichera la liste suivante :
1. SCHED_OTHER the standard round-robin time-sharing policy
2. SCHED_BATCH for "batch" style execution of processes
3. SCHED_IDLE for running very low priority background jobs.
4. SCHED_FIFO a first-in, first-out policy
5. SCHED_RR a round-robin policy
Les processus d'ordonnancement peuvent être divisés en 2 groupes, les politiques d'ordonnancement normales (1 à 3) et les politiques d'ordonnancement en temps réel (4 et 5). Les processus en temps réel auront toujours la priorité sur les processus normaux. Un processus en temps réel peut être appelé à l'aide de la commande suivante (l'exemple montre comment déclarer une politique SCHED_RR) :
chrt --rr <priority between 1-99> ./myProgram
Pour obtenir la valeur PR pour un processus en temps réel, l'équation suivante est appliquée :
PR =-1 - rt_prior
Où rt_prior correspond à la priorité entre 1 et 99. Pour cette raison, le processus qui aura la priorité sur les autres processus sera celui appelé avec le numéro 99.
Il est important de noter que pour les processus en temps réel, la valeur nice n'est pas utilisée.
Pour voir la "gentillesse" actuelle et la valeur PR d'un processus, la commande suivante peut être exécutée :
top
Ce qui affiche la sortie suivante :
Dans la figure, les valeurs PR et NI sont affichées. Il est bon de noter le processus avec la valeur PR -51 qui correspond à une valeur en temps réel. Il existe également certains processus dont la valeur PR est indiquée comme "rt". Cette valeur correspond en fait à une valeur PR de -100.
Ce commentaire dans sched.h est assez définitif :
/*
* Priority of a process goes from 0..MAX_PRIO-1, valid RT
* priority is 0..MAX_RT_PRIO-1, and SCHED_NORMAL/SCHED_BATCH
* tasks are in the range MAX_RT_PRIO..MAX_PRIO-1. Priority
* values are inverted: lower p->prio value means higher priority.
*
* The MAX_USER_RT_PRIO value allows the actual maximum
* RT priority to be separate from the value exported to
* user-space. This allows kernel threads to set their
* priority to a value higher than any user task. Note:
* MAX_RT_PRIO must not be smaller than MAX_USER_RT_PRIO.
*/
Notez cette partie :
Les valeurs de priorité sont inversées :p->prio
inférieur la valeur signifie une priorité plus élevée .
J'ai fait une expérience pour comprendre cela, comme suit :
-
process1 : priorité RT = 40, affinité CPU =CPU 0. Ce processus "tourne" pendant 10 secondes afin de ne laisser aucun processus de priorité inférieure s'exécuter sur le CPU 0.
-
process2 :priorité RT =39, affinité CPU =CPU 0. Ce processus imprime un message sur stdout toutes les 0,5 secondes, en dormant entre les deux. Il imprime le temps écoulé avec chaque message.
J'utilise un noyau 2.6.33 avec le correctif PREEMPT_RT.
Pour exécuter l'expérience, j'exécute process2 dans une fenêtre (en tant que root), puis démarre process1 (en tant que root) dans une autre fenêtre. Le résultat est que process1 semble préempter process2, ne lui permettant pas de s'exécuter pendant 10 secondes complètes.
Dans une deuxième expérience, je change la priorité RT de process2 à 41. Dans ce cas, process2 n'est pas préempté par process1.
Cette expérience montre qu'un grand Valeur de priorité RT en sched_setscheduler()
a une priorité plus élevée. Cela semble contredire ce que Michael Foukarakis a souligné à partir de sched.h, mais en réalité ce n'est pas le cas. Dans sched.c dans les sources du noyau, nous avons :
static void
__setscheduler(struct rq *rq, struct task_struct *p, int policy, int prio)
{
BUG_ON(p->se.on_rq);
p->policy = policy;
p->rt_priority = prio;
p->normal_prio = normal_prio(p);
/* we are holding p->pi_lock already */
p->prio = rt_mutex_getprio(p);
if (rt_prio(p->prio))
p->sched_class = &rt_sched_class;
else
p->sched_class = &fair_sched_class;
set_load_weight(p);
}
rt_mutex_getprio(p) fait ce qui suit :
return task->normal_prio;
Alors que normal_prio() fait ce qui suit :
prio = MAX_RT_PRIO-1 - p->rt_priority; /* <===== notice! */
...
return prio;
En d'autres termes, nous avons (ma propre interprétation) :
p->prio = p->normal_prio = MAX_RT_PRIO - 1 - p->rt_priority
Ouah! C'est déroutant ! Pour résumer :
-
Avec p->prio, une valeur plus petite prévaut sur une valeur plus grande.
-
Avec p->rt_priority, une valeur plus grande préempte une valeur plus petite. Il s'agit de la priorité en temps réel définie à l'aide de
sched_setscheduler()
.