Dans la plage de priorité de processus en temps réel Linux allant de 1 à 99, il m'est difficile de savoir quelle est la priorité la plus élevée, 1 ou 99.
La section 7.2.2 de "Comprendre le noyau Linux" (O'Reilly) indique que 1 est la priorité la plus élevée, ce qui est logique si l'on considère que les processus normaux ont des priorités statiques de 100 à 139, 100 étant la priorité la plus élevée:
"Chaque processus en temps réel est associé à une priorité en temps réel, qui correspond à une valeur comprise entre 1 (priorité la plus élevée) et 99 (priorité la plus faible)."
Par ailleurs, la page de manuel sched_setscheduler (RHEL 6.1) affirme que 99 est la plus haute des valeurs suivantes:
"Les processus planifiés sous l'une des politiques en temps réel (SCHED_FIFO, SCHED_RR) ont une valeur sched_priority comprise entre 1 (faible) et 99 (élevé)."
Quelle est la plus haute priorité en temps réel?
J'ai fait une expérience pour comprendre ce qui suit:
process1: RT priority = 40, affinité de la CPU = CPU 0. Ce processus "tourne" pendant 10 secondes pour ne laisser aucun processus de priorité inférieure s'exécuter sur la CPU 0.
process2: RT priority = 39, CPU affinité = CPU 0. Ce processus imprime un message sur stdout toutes les 0,5 seconde, en dormant entre les deux. Il affiche le temps écoulé avec chaque message.
J'exécute un noyau 2.6.33 avec le correctif PREEMPT_RT.
Pour exécuter le test, je lance process2 dans une fenêtre (en tant que root), puis lance 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 en 41. Dans ce cas, process2 est et non préempté par process1 .
Cette expérience montre qu’une plus grande RT valeur de priorité dans sched_setscheduler () a une priorité plus élevée. Cela semble contredire ce Michael Foukarakis a indiqué à sched.h, mais ce n’est en fait pas le cas. Dans sched.c dans la source 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) effectue les opérations suivantes:
return task->normal_prio;
Alors que normal_prio () arrive à faire 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
Hou la la! C'est déroutant! Résumer:
Avec p-> prio, une valeur plus petite prévient une valeur plus grande.
Avec p-> rt_priority, une valeur plus grande prévient une valeur plus petite. C'est la priorité en temps réel définie à l'aide de sched_setscheduler ().
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: lower p->prio
valeur signifie une priorité plus élevée .
Pour déterminer la priorité en temps réel la plus élevée que vous puissiez définir par programme, utilisez la fonction sched_get_priority_max.
Sous Linux 2.6.32, un appel à sched_get_priority_max (SCHED_FIFO) renvoie 99.
Réponse courte
99 sera le gagnant pour la priorité en temps réel.
PR est le niveau de priorité (plage -100 à 40). Plus le PR est bas, plus la priorité du processus sera élevée.
Le PR est calculé comme suit:
Réponse longue
Il existe 2 types de processus, le normal et le temps réel Pour les processus normaux (et uniquement pour ceux-ci), Nice est appliqué comme suit:
Nice
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 de Nice et PR le niveau de priorité. Comme nous pouvons le constater, le -20 correspond en fait à 0, tandis que le 19 en correspond à 39.
Par défaut, une valeur de programme Nice est égale à 0 bit. Il est possible pour un utilisateur root de lancer des programmes avec une valeur Nice spécifiée à l'aide de la commande suivante:
Nice -n <Nice_value> ./myProgram
Temps réel
Nous pourrions aller encore plus loin. La priorité de Nice est en réalité 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 à la dernière partie de la plage (de 100 à 139). Cette équation laisse les valeurs de 0 à 99 inaccessibles, ce qui correspond à un niveau de PR négatif (de -100 à -1). Pour pouvoir accéder à ces valeurs, le processus doit être défini en "temps réel".
Il existe 5 politiques de planification dans un environnement LINUX qui peuvent être affichées à l'aide de la commande suivante:
chrt -m
Ce qui montrera 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 de planification peuvent être divisés en 2 groupes, les stratégies de planification normales (1 à 3) et les stratégies de planification 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 (voici comment déclarer une règle SCHED_RR):
chrt --rr <priority between 1-99> ./myProgram
Pour obtenir la valeur PR d'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é la plus élevée par rapport aux 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 de 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 montre 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 temps réel. Il existe également des processus dont la valeur PR est indiquée par "rt". Cette valeur correspond en fait à une valeur PR de -100.
Nous avons le nombre 40 en tant que nombre de priorités de processus en temps non réel pour BATCH, AUTRES stratégies qui varient de 0 à 39 pas de 100 à 139. Vous pouvez le constater en regardant tout processus du système qui n'est pas en temps réel. processus. Il portera un PR de 20 et un degré de 0 par défaut. Si vous diminuez la gentillesse d'un processus (généralement, diminuez ou négativement le nombre, diminuez la gentillesse, augmentez le processus), disons de 0 à -1, vous constaterez que la priorité diminuera de 19 à 19, ce qui indique simplement Si vous rendez un processus plus gourmand ou si vous souhaitez attirer un peu plus l’attention en diminuant la valeur de gentillesse du PID, vous obtiendrez également une priorité plus élevée, diminuez donc le nombre de PRIORITY SUPÉRIEUR DE PRIORITÉ.
Example:
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
2079 admin 10 -10 280m 31m 4032 S 9.6 0.0 21183:05 mgmtd
[[email protected] ~]# renice -n -11 2079
2079: old priority -10, new priority -11
[[email protected] ~]# top -b | grep mgmtd
2079 admin 9 -11 280m 31m 4032 S 0.0 0.0 21183:05 mgmtd
^C
J'espère que cet exemple concret clarifie les doutes et peut aider à corriger les mots de source incorrecte, le cas échéant.
Votre hypothèse selon laquelle les processus normaux ont des priorités statiques comprises entre 100 et 139 est, dans le meilleur des cas, volatile et non valide au pire. Ce que je veux dire, c'est que: set_scheduler permet uniquement à sched_priority d'être 0 (ce qui indique un planificateur de priorité dynamique) avec SCHED_OTHER/SCHED_BATCH et SCHED_IDLE (true à la date du 2.6.16).
Les priorités statiques programmatiques sont 1-99 uniquement pour SCHED_RR et SCHED_FIFO
Vous pouvez maintenant voir les priorités 100-139 utilisées en interne par un planificateur dynamique. Cependant, ce que le noyau fait en interne pour gérer les priorités dynamiques (y compris l'inversion du sens priorité élevée/priorité basse pour faciliter la comparaison ou le tri) devrait être opaque. à l'espace utilisateur.
N'oubliez pas que dans SCHED_OTHER, vous remplissez principalement les processus dans la même file d'attente prioritaire.
L'idée est de rendre le noyau plus facile à déboguer et d'éviter les erreurs loufoques.
Ainsi, la logique de changement de signification pourrait être que, en tant que développeur du noyau, ne souhaite pas utiliser les mathématiques comme 139-idx (juste au cas où idx> 139) ... il vaut mieux faire les mathématiques avec idx-100 et inverser le concept. faible ou élevé, car idx <100 est bien compris.
Un autre effet secondaire est que la gentillesse devient plus facile à gérer. 100 - 100 <=> Nice == 0; 101-100 <=> Nice == 1; etc. est plus facile. Il se réduit très bien aussi aux nombres négatifs (RIEN à faire avec des priorités statiques) 99 - 100 <=> Nice == -1 ...