Ogni processo nasce con nice 0

Il kernel assegna a ogni processo una priorità statica. Da 0 a 99 stanno i processi real-time, da 100 a 139 i processi normali: tutto quello che amministri di solito vive nella seconda fascia, e il valore di partenza è 120. Attenzione al verso, perché è controintuitivo: numero più basso significa priorità più alta.

Dentro quella fascia agisce il valore di nice, che va da -20 (per niente gentile, massima urgenza) a 19 (gentilissimo, ultima fila). Ogni processo nuovo parte da nice 0, cioè da priorità 120. Il nome viene proprio dall’idea che un processo gentile lasci passare gli altri davanti a sé.

Tre fatti che l’esame dà per acquisiti:

  • il valore di nice si eredita, quindi un comando lanciato da una shell già a 5 nasce a 5 e non a 0;
  • solo root può scendere sotto zero;
  • un utente normale può soltanto alzare il proprio nice, cioè peggiorarsi, e la modifica non è reversibile: non puoi riportare a 0 un processo che hai messo a 10.

Il nice agisce solo sulla politica di scheduling normale. I processi real-time non si toccano né con nice né con renice.

Leggere il valore: ps e top mostrano numeri diversi

La colonna del nice si chiama NI ovunque ed è l’unica che si legge sempre allo stesso modo. La priorità no.

$ ps -el
F S   UID   PID  PPID  C PRI  NI ADDR SZ WCHAN  TTY          TIME CMD
4 S     0     1     0  0  80   0 -  9292 -      ?        00:00:00 systemd
1 I     0     3     2  0  60 -20 -     0 -      ?        00:00:00 rcu_gp
1 S     0    12     2  0 -40   - -     0 -      ?        00:00:08 migration/0

ps -el (identico a ps -Al) mostra PRI su una scala storica che va da -40 a 99: per ottenere il valore del kernel devi sommare 40, quindi PRI 80 corrisponde a 120. Un PRI negativo indica un processo real-time, che infatti non ha un nice e nella colonna NI mostra un trattino.

top usa una terza convenzione: nella colonna PR i processi normali vanno da 0 a 39, con 20 come default, e i real-time compaiono come rt oppure con un numero negativo. Se vuoi il numero vero senza conversioni, leggilo da /proc:

$ grep ^prio /proc/1/sched
prio                   :       120

Per una vista su misura conviene ps con output esplicito, per esempio ps -eo pid,ni,pri,user,comm --sort=-pcpu.

Partire già gentili: nice

nice senza argomenti stampa il nice della shell corrente. Con un comando lo esegue con un nice modificato, e senza opzioni l’aggiustamento predefinito è 10 — non 1 e non 0.

$ nice
0
$ nice -n 15 tar czf /srv/backup.tar.gz /srv/dati
$ nice nice -n 3 nice
13

L’ultimo esempio dice una cosa che vale la pena fissare: l’argomento di -n è un incremento relativo al nice corrente, non un valore assoluto. Il primo nice porta a 10, il secondo aggiunge 3 e si arriva a 13.

Due trappole. La prima è la sintassi storica nice -15 comando: quel -15 è l’aggiustamento e vale +15, non -15. Usa sempre -n, e per un valore negativo scrivi sudo nice -n -10 comando. La seconda è che se chiedi un aggiustamento negativo senza permessi GNU nice non fallisce: stampa un avviso e prosegue come se avessi chiesto 0. Il comando parte comunque, solo non con la priorità che credevi.

Cambiare idea a processo avviato: renice e top

renice agisce su processi già in esecuzione, indicati per PID con -p, per gruppo con -g, per utente con -u.

# renice -n -10 -p 2164
2164 (process ID) old priority 0, new priority -10
# renice -n 5 -u marco
# renice -n 5 -g sviluppo

Qui sta la differenza che si sbaglia più spesso. Nell’implementazione util-linux, quella che trovi su qualunque distribuzione Linux, il valore passato a renice è assoluto, mentre POSIX lo definisce relativo: renice -n 5 su un processo già a 5 lo lascia a 5, non lo porta a 10. Per un incremento vero esiste l’opzione --relative. E se usi -n, deve essere il primo argomento; renice 5 -p 2164, senza opzione, funziona ugualmente.

Se un utente non privilegiato prova ad abbassare il nice ottiene un errore netto, non un avviso:

$ renice -10 21704
renice: failed to set priority for 21704 (process ID): Permission denied

La stessa operazione si fa da top: premi r, digita il PID (ne viene proposto uno di default, il primo della lista) e poi il nuovo valore di nice.

Quello che conviene sapere a memoria

Questo obiettivo è fatto di dettagli da digitare, non da riconoscere: l’intervallo da -20 a 19, il default 0, la priorità 120, i 40 di differenza fra ps e kernel, nice -n, renice -n con -p, -u o -g, il tasto r di top. Ripetili finché non ti vengono senza pensarci.