103.6 Lezione 1
Certificazione: |
LPIC-1 |
---|---|
Versione: |
5.0 |
Argomento: |
103 Comandi GNU e Unix |
Obiettivo: |
103.6 Modificare le priorità di esecuzione di un processo |
Lezione: |
1 di 1 |
Introduzione
I sistemi operativi in grado di eseguire più di un processo contemporaneamente sono chiamati sistemi multi-tasking o multi-elaborazione. Mentre la vera simultaneità si verifica solo quando è disponibile più di un’unità di elaborazione, anche i sistemi a processore singolo possono simulare la simultaneità passando da un processo all’altro molto rapidamente. Questa tecnica viene impiegata anche in sistemi con molte CPU equivalenti, o sistemi symmetric multi-processor (SMP), dato che il numero di potenziali processi simultanei supera notevolmente il numero di unità processore disponibili.
Infatti, solo un processo alla volta può utilizzare la CPU. Tuttavia, la maggior parte delle attività del processo sono chiamate di sistema (system calls), ovvero il processo in esecuzione trasferisce il controllo della CPU ad un altro processo in modo che anch’esso esegua l’operazione richiesta. Le chiamate di sistema sono responsabili di tutte le comunicazioni tra dispositivi, come allocazioni di memoria, lettura e scrittura sui file system, stampa di testo sullo schermo, interazione dell’utente, trasferimenti di rete e così via. Il trasferimento del controllo della CPU durante una chiamata di sistema consente al sistema operativo di decidere se per riportare il controllo della CPU al processo precedente o per passarlo a un altro processo. Poiché le moderne CPU possono eseguire le istruzioni molto più velocemente di quanto la maggior parte dell’hardware esterno possa comunicare, un nuovo processo di controllo può svolgere molto lavoro sulla CPU mentre le risposte hardware richieste in precedenza non sono ancora disponibili. Per garantire il massimo sfruttamento della CPU, i sistemi operativi multielaborazione mantengono una coda dinamica di processi attivi in attesa di uno slot di tempo della CPU.
Sebbene consentano di migliorare significativamente l’utilizzo del tempo della CPU, fare affidamento esclusivamente sulle chiamate di sistema per passare da un processo all’altro non è sufficiente per ottenere prestazioni multi-tasking soddisfacenti. Un processo che non effettua chiamate di sistema potrebbe utilizzare la CPU a tempo indeterminato. Questo è il motivo per cui i sistemi operativi moderni sono anche preemptive, ovvero un processo in esecuzione può essere rimesso in coda in modo che un processo più importante possa usare la CPU, anche se il processo in esecuzione non ha effettuato una chiamata di sistema.
Il Linux Scheduler
Linux, come sistema operativo multi-elaborazione preventivo (preemptive), implementa uno scheduler che organizza la coda dei processi. Più precisamente, lo scheduler decide anche quale thread accodato verrà eseguito - un processo può ramificare molti thread indipendenti - ma processo e thread sono termini intercambiabili in questo contesto. Ogni processo ha due predicati che intervengono sulla sua schedulazione: la scheduling policy e la scheduling priority.
Esistono due tipi principali di criteri di pianificazione (scheduling): politiche in tempo reale e politiche normali. I processi nell’ambito di una politica in tempo reale sono programmati direttamente dai loro valori di priorità. Se un processo più importante diventa pronto per essere eseguito, un processo in esecuzione meno importante viene interrotto e il processo con priorità più alta assume il controllo della CPU. Un processo con priorità più bassa otterrà il controllo della CPU solo se i processi con priorità più alta sono inattivi o in attesa di risposta hardware.
Qualsiasi processo in tempo reale ha una priorità maggiore rispetto a un processo normale. Come sistema operativo generico, Linux esegue solo pochi processi in tempo reale. La maggior parte dei processi, inclusi i programmi di sistema e utente, vengono eseguiti secondo i normali criteri di pianificazione. I processi normali di solito hanno lo stesso valore di priorità, ma le politiche normali possono definire regole di priorità di esecuzione utilizzando un altro predicato di processo: il nice value. Per evitare confusione con le priorità dinamiche derivate da valori accettabili, le priorità di pianificazione sono solitamente chiamate priorità di pianificazione statiche.
Lo scheduler di Linux può essere configurato in molti modi diversi ed esistono modi ancora più complessi per stabilire le priorità, ma questi concetti generali si applicano sempre. Durante l’ispezione e l’ottimizzazione della pianificazione dei processi, è importante tenere presente che saranno interessati solo i processi con i normali criteri di pianificazione.
Leggere le Priorità
Linux riserva priorità statiche che vanno da 0 a 99 per i processi in tempo reale e priorità statiche che vanno da 100 a 139 per i processi normali, il che significa che ci sono 39 diversi livelli di priorità per i processi normali. Valori più bassi significano priorità più alta. La priorità statica di un processo attivo può essere trovata nel file sched
, situato nella sua rispettiva directory all’interno del filesystem /proc
$ grep ^prio /proc/1/sched prio : 120
Come mostrato nell’esempio, la riga che inizia con prio
fornisce il valore di priorità del processo (il processo PID 1 è il processo init o systemd, il primo processo che il kernel avvia durante l’inizializzazione del sistema). La priorità standard per i processi normali è 120, quindi può essere ridotta a 100 o aumentata a 139. Le priorità di tutti i processi in esecuzione possono essere verificate con il comando ps -Al
o ps -el
:
$ 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 4 S 0 19 1 0 80 0 - 8817 - ? 00:00:00 systemd-journal 4 S 104 61 1 0 80 0 - 64097 - ? 00:00:00 rsyslogd 4 S 0 63 1 0 80 0 - 7244 - ? 00:00:00 cron 1 S 0 126 1 0 80 0 - 4031 - ? 00:00:00 dhclient 4 S 0 154 1 0 80 0 - 3937 - pts/0 00:00:00 agetty 4 S 0 155 1 0 80 0 - 3937 - pts/1 00:00:00 agetty 4 S 0 156 1 0 80 0 - 3937 - pts/2 00:00:00 agetty 4 S 0 157 1 0 80 0 - 3937 - pts/3 00:00:00 agetty 4 S 0 158 1 0 80 0 - 3937 - console 00:00:00 agetty 4 S 0 160 1 0 80 0 - 16377 - ? 00:00:00 sshd 4 S 0 280 0 0 80 0 - 5301 - ? 00:00:00 bash 0 R 0 392 280 0 80 0 - 7221 - ? 00:00:00 ps
La colonna PRI
indica la priorità statica assegnata dal kernel. Notare, tuttavia, che il valore di priorità visualizzato da ps
è diverso da quello ottenuto nell’esempio precedente. Per ragioni storiche, le priorità visualizzate da ps
vanno da -40 a 99 per impostazione predefinita, quindi la priorità effettiva si ottiene aggiungendovi 40 (in particolare, 80 + 40 = 120).
È anche possibile monitorare continuamente i processi attualmente gestiti dal kernel Linux con il programma top
. Come con ps
, anche top
mostra il valore di priorità in modo diverso. Per rendere più facile l’identificazione dei processi in tempo reale, top
sottrae il valore di priorità di 100, rendendo così tutte le priorità in tempo reale negative, con un numero negativo o rt che le identifica. Pertanto, le priorità normali visualizzate da top
vanno da 0 a 39.
Note
|
Per ottenere maggiori dettagli dal comando $ ps -e -o user,uid,comm,tty,pid,ppid,pri,pmem,pcpu --sort=-pcpu | head |
La Niceness del processo
Ogni processo normale inizia con un valore di niceness predefinito di 0 (priorità 120). Il nome nice deriva dall’idea che i processi “più gentili” consentono ad altri processi di essere eseguiti prima di loro in una particolare coda di esecuzione. I numeri di niceness vanno da -20 (meno gentilezza, priorità alta) a 19 (più gentilezza, priorità bassa). Linux consente anche di assegnare diversi valori di niceness ai thread all’interno dello stesso processo. La colonna "NI" nell’output ps
indica il numero nice.
Solo l’utente root può diminuire la niceness di un processo sotto lo zero. È possibile avviare un processo con una priorità non standard con il comando nice
. Per impostazione predefinita, nice
cambia la niceness in 10, ma può essere specificato con l’opzione -n
:
$ nice -n 15 tar czf home_backup.tar.gz /home
In questo esempio, il comando tar
viene eseguito con una niceness di 15. Il comando renice
può essere usato per cambiare la priorità di un processo in esecuzione. L’opzione -p
indica il numero PID del processo di destinazione. Per esempio:
# renice -10 -p 2164 2164 (process ID) old priority 0, new priority -10
Le opzioni -g
e -u
sono usate per modificare rispettivamente tutti i processi di un gruppo o di un utente specifico. Con renice +5 -g users
, la niceness dei processi posseduti dagli utenti del gruppo users sarà aumentata a 5.
Oltre a renice
, la priorità dei processi può essere modificata con altri programmi, come il programma top
. Nella schermata principale in alto, la niceness di un processo può essere modificata premendo r
e quindi il numero PID del processo:
top - 11:55:21 up 23:38, 1 user, load average: 0,10, 0,04, 0,05 Tasks: 20 total, 1 running, 19 sleeping, 0 stopped, 0 zombie %Cpu(s): 0,5 us, 0,3 sy, 0,0 ni, 99,0 id, 0,0 wa, 0,2 hi, 0,0 si, 0,0 st KiB Mem : 4035808 total, 774700 free, 1612600 used, 1648508 buff/cache KiB Swap: 7999828 total, 7738780 free, 261048 used. 2006688 avail Mem PID to renice [default pid = 1] PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND 1 root 20 0 74232 7904 6416 S 0,000 0,196 0:00.12 systemd 15 root 20 0 67436 6144 5568 S 0,000 0,152 0:00.03 systemd-journal 21 root 20 0 61552 5628 5000 S 0,000 0,139 0:00.01 systemd-logind 22 message+ 20 0 43540 4072 3620 S 0,000 0,101 0:00.03 dbus-daemon 23 root 20 0 45652 6204 4992 S 0,000 0,154 0:00.06 wickedd-dhcp4 24 root 20 0 45648 6276 5068 S 0,000 0,156 0:00.06 wickedd-auto4 25 root 20 0 45648 6272 5060 S 0,000 0,155 0:00.06 wickedd-dhcp6
Il messaggio PID to renice [default pid = 1]
appare con il primo processo elencato selezionato per impostazione predefinita. Per modificare la priorità di un altro processo, digita il suo PID e premi Invio. Apparirà quindi il messaggio Renice PID 1 to value
(con il numero PID richiesto) e sarà possibile assegnare un nuovo valore di niceness.
Esercizi Guidati
-
In un sistema multitasking preventivo, cosa succede quando un processo con priorità inferiore occupa il processore e un processo con priorità più alta viene messo in coda per essere eseguito?
-
Osserva la seguente schermata di
top
:top - 08:43:14 up 23 days, 12:29, 5 users, load average: 0,13, 0,18, 0,21 Tasks: 240 total, 2 running, 238 sleeping, 0 stopped, 0 zombie %Cpu(s): 1,4 us, 0,4 sy, 0,0 ni, 98,1 id, 0,0 wa, 0,0 hi, 0,0 si, 0,0 st MiB Mem : 7726,4 total, 590,9 free, 1600,8 used, 5534,7 buff/cache MiB Swap: 30517,0 total, 30462,5 free, 54,5 used. 5769,4 avail Mem PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND 1 root 20 0 171420 10668 7612 S 0,0 0,1 9:59.15 systemd 2 root 20 0 0 0 0 S 0,0 0,0 0:02.76 kthreadd 3 root 0 -20 0 0 0 I 0,0 0,0 0:00.00 rcu_gp 4 root 0 -20 0 0 0 I 0,0 0,0 0:00.00 rcu_par_gp 8 root 0 -20 0 0 0 I 0,0 0,0 0:00.00 mm_percpu_wq 9 root 20 0 0 0 0 S 0,0 0,0 0:49.06 ksoftirqd/0 10 root 20 0 0 0 0 I 0,0 0,0 18:24.20 rcu_sched 11 root 20 0 0 0 0 I 0,0 0,0 0:00.00 rcu_bh 12 root rt 0 0 0 0 S 0,0 0,0 0:08.17 migration/0 14 root 20 0 0 0 0 S 0,0 0,0 0:00.00 cpuhp/0 15 root 20 0 0 0 0 S 0,0 0,0 0:00.00 cpuhp/1 16 root rt 0 0 0 0 S 0,0 0,0 0:11.79 migration/1 17 root 20 0 0 0 0 S 0,0 0,0 0:26.01 ksoftirqd/1
Quali PID hanno priorità in tempo reale?
-
Osserva il seguente elenco
ps -el
:F S UID PID PPID C PRI NI ADDR SZ WCHAN TTY TIME CMD 4 S 0 1 0 0 80 0 - 42855 - ? 00:09:59 systemd 1 S 0 2 0 0 80 0 - 0 - ? 00:00:02 kthreadd 1 I 0 3 2 0 60 -20 - 0 - ? 00:00:00 rcu_gp 1 S 0 9 2 0 80 0 - 0 - ? 00:00:49 ksoftirqd/0 1 I 0 10 2 0 80 0 - 0 - ? 00:18:26 rcu_sched 1 I 0 11 2 0 80 0 - 0 - ? 00:00:00 rcu_bh 1 S 0 12 2 0 -40 - - 0 - ? 00:00:08 migration/0 1 S 0 14 2 0 80 0 - 0 - ? 00:00:00 cpuhp/0 5 S 0 15 2 0 80 0 - 0 - ? 00:00:00 cpuhp/1
Quale PID ha la priorità più alta?
-
Dopo aver provato a rinominare un processo con
renice
, si verifica il seguente errore:$ renice -10 21704 renice: failed to set priority for 21704 (process ID): Permission denied
Qual è la probabile causa dell’errore?
Esercizi Esplorativi
-
La modifica delle priorità del processo è generalmente richiesta quando un processo occupa troppo tempo della CPU. Usando
ps
con le opzioni standard per visualizzare tutti i processi di sistema in formato lungo, quale flag--sort
ordinerà i processi in base all’utilizzo della CPU, aumentando l’ordine? -
Il comando
schedtool
può impostare tutti i parametri di pianificazione della CPU di cui Linux è capace o visualizzare informazioni per determinati processi. Come può essere utilizzato per visualizzare i parametri di schedulazione del processo1750
? Inoltre, come può essere usatoschedtool
per cambiare il processo1750
in tempo reale con priorità-90
(come mostrato datop
)?
Sommario
Questa lezione illustra come Linux condivide il tempo della CPU tra i suoi processi gestiti. Per garantire le migliori prestazioni, i processi più critici devono superare i processi meno critici. La lezione segue i seguenti passaggi:
-
Concetti di base sui sistemi multi-processing.
-
Che cos’è uno scheduler di processo e come Linux lo implementa.
-
Quali sono le priorità di Linux, i valori di niceness e il loro scopo.
-
Come leggere e interpretare le priorità del processo in Linux.
-
Come modificare la priorità di un processo, prima e durante la sua esecuzione
Risposte agli Esercizi Guidati
-
In un sistema multitasking preventivo, cosa succede quando un processo con priorità inferiore occupa il processore e un processo con priorità più alta viene messo in coda per essere eseguito?
Il processo con priorità più bassa si interrompe e al suo posto viene eseguito il processo con priorità più alta.
-
Osserva la seguente schermata di
top
:top - 08:43:14 up 23 days, 12:29, 5 users, load average: 0,13, 0,18, 0,21 Tasks: 240 total, 2 running, 238 sleeping, 0 stopped, 0 zombie %Cpu(s): 1,4 us, 0,4 sy, 0,0 ni, 98,1 id, 0,0 wa, 0,0 hi, 0,0 si, 0,0 st MiB Mem : 7726,4 total, 590,9 free, 1600,8 used, 5534,7 buff/cache MiB Swap: 30517,0 total, 30462,5 free, 54,5 used. 5769,4 avail Mem PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND 1 root 20 0 171420 10668 7612 S 0,0 0,1 9:59.15 systemd 2 root 20 0 0 0 0 S 0,0 0,0 0:02.76 kthreadd 3 root 0 -20 0 0 0 I 0,0 0,0 0:00.00 rcu_gp 4 root 0 -20 0 0 0 I 0,0 0,0 0:00.00 rcu_par_gp 8 root 0 -20 0 0 0 I 0,0 0,0 0:00.00 mm_percpu_wq 9 root 20 0 0 0 0 S 0,0 0,0 0:49.06 ksoftirqd/0 10 root 20 0 0 0 0 I 0,0 0,0 18:24.20 rcu_sched 11 root 20 0 0 0 0 I 0,0 0,0 0:00.00 rcu_bh 12 root rt 0 0 0 0 S 0,0 0,0 0:08.17 migration/0 14 root 20 0 0 0 0 S 0,0 0,0 0:00.00 cpuhp/0 15 root 20 0 0 0 0 S 0,0 0,0 0:00.00 cpuhp/1 16 root rt 0 0 0 0 S 0,0 0,0 0:11.79 migration/1 17 root 20 0 0 0 0 S 0,0 0,0 0:26.01 ksoftirqd/1
Quali PID hanno priorità in tempo reale?
PIDs 12 e 16.
-
Osserva il seguente elenco
ps -el
::F S UID PID PPID C PRI NI ADDR SZ WCHAN TTY TIME CMD 4 S 0 1 0 0 80 0 - 42855 - ? 00:09:59 systemd 1 S 0 2 0 0 80 0 - 0 - ? 00:00:02 kthreadd 1 I 0 3 2 0 60 -20 - 0 - ? 00:00:00 rcu_gp 1 S 0 9 2 0 80 0 - 0 - ? 00:00:49 ksoftirqd/0 1 I 0 10 2 0 80 0 - 0 - ? 00:18:26 rcu_sched 1 I 0 11 2 0 80 0 - 0 - ? 00:00:00 rcu_bh 1 S 0 12 2 0 -40 - - 0 - ? 00:00:08 migration/0 1 S 0 14 2 0 80 0 - 0 - ? 00:00:00 cpuhp/0 5 S 0 15 2 0 80 0 - 0 - ? 00:00:00 cpuhp/1
Quale PID ha la priorità più alta?
PID 12.
-
Dopo aver provato a rinominare un processo con
renice
, si verifica il seguente errore:$ renice -10 21704 renice: failed to set priority for 21704 (process ID): Permission denied
Qual è la probabile causa dell’errore?
Solo l’utente root può diminuire i valori di niceness sotto lo zero.
Risposte agli Esercizi Esplorativi
-
La modifica delle priorità del processo è generalmente richiesta quando un processo occupa troppo tempo della CPU. Usando
ps
con le opzioni standard per visualizzare tutti i processi di sistema in formato lungo, quale flag--sort
ordinerà i processi in base all’utilizzo della CPU, aumentando l’ordine?$ ps -el --sort=pcpu
-
Il comando
schedtool
può impostare tutti i parametri di pianificazione della CPU di cui Linux è capace o visualizzare informazioni per determinati processi. Come può essere utilizzato per visualizzare i parametri di schedulazione del processo1750
? Inoltre, come può essere usatoschedtool
per cambiare il processo1750
in tempo reale con priorità-90
(come mostrato datop
)?$ schedtool 1750
$ schedtool -R -p 89 1750