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.