Respuesta corta
99 será el ganador por prioridad en tiempo real.
PR es el nivel de prioridad (rango -100 a 39). Cuanto menor sea el PR, mayor será la prioridad del proceso.
PR se calcula de la siguiente manera:
- para procesos normales:PR =20 + NI (NI es agradable y varía de -20 a 19)
- para procesos en tiempo real:PR =- 1 - real_time_priority(real_time_priority varía de 1 a 99)
Respuesta larga
Hay 2 tipos de procesos, los normales unos y el tiempo real Para los normales (y solo para esos), se aplica agradable de la siguiente manera:
Agradable
La escala de "amabilidad" va de -20 a 19, siendo -20 la prioridad más alta y 19 la prioridad más baja. El nivel de prioridad se calcula de la siguiente manera:
PR =20 + NI
Donde NI es el nivel agradable y PR es el nivel de prioridad. Entonces, como podemos ver, el -20 en realidad se asigna a 0, mientras que el 19 se asigna a 39.
De forma predeterminada, el valor agradable de un programa es de 0 bits. Es posible que un usuario root ejecute programas con un valor agradable especificado utilizando el siguiente comando:
nice -n <nice_value> ./myProgram
Tiempo Real
Podríamos ir aún más lejos. La prioridad agradable se usa realmente para los programas de usuario. Mientras que la prioridad general de UNIX/LINUX tiene un rango de 140 valores, el valor agradable permite que el proceso se asigne a la última parte del rango (de 100 a 139). Esta ecuación deja inalcanzables los valores de 0 a 99 que corresponderán a un nivel de PR negativo (de -100 a -1). Para poder acceder a esos valores, el proceso debe establecerse como "tiempo real".
Hay 5 políticas de programación en un entorno LINUX que se pueden mostrar con el siguiente comando:
chrt -m
Lo cual mostrará la siguiente lista:
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
Los procesos de programación se pueden dividir en 2 grupos, las políticas de programación normal (1 a 3) y las políticas de programación en tiempo real (4 y 5). Los procesos en tiempo real siempre tendrán prioridad sobre los procesos normales. Se puede llamar a un proceso en tiempo real usando el siguiente comando (el ejemplo es cómo declarar una política SCHED_RR):
chrt --rr <priority between 1-99> ./myProgram
Para obtener el valor de PR para un proceso en tiempo real se aplica la siguiente ecuación:
PR =-1 - rt_prior
Donde rt_prior corresponde a la prioridad entre 1 y 99. Por ello el proceso que tendrá mayor prioridad sobre otros procesos será el que se llame con el número 99.
Es importante tener en cuenta que para los procesos en tiempo real, no se utiliza el valor agradable.
Para ver la "amabilidad" actual y el valor PR de un proceso, se puede ejecutar el siguiente comando:
top
Que muestra el siguiente resultado:
En la figura se muestran los valores de PR y NI. Es bueno notar el proceso con valor PR -51 que corresponde a un valor en tiempo real. También hay algunos procesos cuyo valor PR se indica como "rt". Este valor en realidad corresponde a un valor PR de -100.
Este comentario en sched.h es bastante definitivo:
/*
* 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.
*/
Tenga en cuenta esta parte:
Los valores de prioridad están invertidos:menor p->prio
valor significa mayor prioridad .
Hice un experimento para concretar esto, de la siguiente manera:
-
proceso1:prioridad RT =40, afinidad de CPU =CPU 0. Este proceso "gira" durante 10 segundos para que no permita que ningún proceso de menor prioridad se ejecute en la CPU 0.
-
proceso2:prioridad RT =39, afinidad de CPU =CPU 0. Este proceso imprime un mensaje en la salida estándar cada 0,5 segundos, durmiendo en el medio. Imprime el tiempo transcurrido con cada mensaje.
Estoy ejecutando un kernel 2.6.33 con el parche PREEMPT_RT.
Para ejecutar el experimento, ejecuto el proceso 2 en una ventana (como raíz) y luego inicio el proceso 1 (como raíz) en otra ventana. El resultado es que el proceso 1 parece adelantarse al proceso 2, lo que no permite que se ejecute durante 10 segundos completos.
En un segundo experimento, cambio la prioridad RT de process2 a 41. En este caso, process2 no reemplazado por proceso1.
Este experimento muestra que un más grande Valor de prioridad RT en sched_setscheduler()
tiene mayor prioridad. Esto parece contradecir lo que señaló Michael Foukarakis de sched.h, pero en realidad no es así. En sched.c en el código fuente del kernel, tenemos:
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) hace lo siguiente:
return task->normal_prio;
Mientras normal_prio() pasa a hacer lo siguiente:
prio = MAX_RT_PRIO-1 - p->rt_priority; /* <===== notice! */
...
return prio;
En otras palabras, tenemos (mi propia interpretación):
p->prio = p->normal_prio = MAX_RT_PRIO - 1 - p->rt_priority
¡Guau! ¡Eso es confuso! Para resumir:
-
Con p->prio, un valor menor reemplaza a un valor mayor.
-
Con p->rt_priority, un valor mayor reemplaza a un valor menor. Esta es la prioridad en tiempo real establecida usando
sched_setscheduler()
.