# Processi

Ogni volta che eseguiamo un comando, vengono avviati uno o piu' processi.

## Controllare i job

I *job* sono processi che sono stati avviati in modo interattivo tramite una shell, inviati in background e non hanno terminato l'esecuzione. Per scoprire i job attivi, digitare sul terminale il comando:

```bash
 > jobs
[1]+  Stopped                 sleep 60
```
- Il simbolo `[1]` rappresenta l'ID del job e puo' essere usato, preceduto dal simbolo `%`, per cambiare lo stato del job, attraverso le utility `fg`, `bg`, e `kill`.
- `+`: indica il job corrente, ovvero l'ultimo messo in background. Il job precedente e' contrassegnato da un segno `-`. Eventuali altri job precedenti non sono contrassegnati
- `Stopped`: indica lo stato del job
- `sleep 60`: il comando

Con l'opzione `-l` viene mostrato anche il `PID` del processo:

```bash
 > jobs -l
[1]+ 13637 Fermato                 sleep 60
```

> Un job ha sia un job ID che un process ID (PID)

### Stato dei job

Una volta che un job e' in background o sospeso:

- Portarlo in primo piano con `fg`

```bash
 > fg %1
sleep 60
```

- Portarlo in background con `bg`

```bash
 > bg %1
[1]+ sleep 60 &
```

- Terminarlo col comando `kill`

```bash
 > kill %1
[1]+  Terminato               sleep 60
```

### Detach dei job: nohup

Negli esempi precedenti, i job erano legati alla sessione dell'utente. Se termina, terminano anche i job. E' possibile scollegare un job dalla sessione, in modo che, se termina la sessione, non viene terminato anche il job.

```bash
nohup COMMAND &
```

Nel file `nohup.out` verranno salvati *stdin* e *stderr* in modo predefinito. 

```bash
 > nohup ping localhost &
[1] 14081
nohup: input ignorato e output accodato a 'nohup.out'
```

Nel caso volessimo indicare un file personalizzato: `nohup ping localhost > /path/to/file &`

Per terminare il processo: `kill %1` oppure `kill 14081`

## Controllare i processi

Un processo e' un'istanza di un programma in esecuzione.

### Inviare segnali ai processi

Ogni processo ha un identificatore univoco o `PID`. Un modo per scoprirlo e' tramite il comando `pgrep PROCESS_NAME` 

```bash
 > pgrep sleep
14384
14515
```

Oppure anche tramite:

```bash
 > pidof sleep
14515 14384
```

Il comando `pkill` termina il processo. Per terminare tutte le istanze dello stesso processo, e' possibile utilizzare il comando `killall`. I comandi `kill`, `pkill` e `killall` inviano un segnale di terminazione al processo. Se non specificato, viene inviato il valore predefinito di SIGTERM. I segnali di terminazione possono essere specificati anche mediante numero. Usare `kill -9` per terminare un processo quando qualsiasi altro segnale fallisce.

### Segnali di terminazione

Il segnale SIGTERM (*Signal Terminate*) è uno dei segnali utilizzati nel sistema operativo Unix e nei suoi derivati per gestire la terminazione dei processi. Quando un processo riceve un segnale SIGTERM, viene avvisato di terminare in modo controllato. Questo significa che il processo ha la possibilità di eseguire operazioni di pulizia, come il salvataggio dei dati o la chiusura delle risorse aperte, prima di terminare.

Oltre a SIGTERM, ci sono altri segnali di terminazione:

- SIGKILL (Uccisione): Questo segnale forza la terminazione immediata del processo. Non può essere gestito o ignorato dal processo, e non consente alcuna operazione di pulizia. È utilizzato quando un processo non risponde a SIGTERM.

- SIGINT (Interruzione): Questo segnale viene inviato quando un utente preme Ctrl+C in un terminale. È simile a SIGTERM, in quanto consente al processo di gestire la terminazione in modo controllato.

Alcuni segnali possono essere ignorati, ma non SIGKILL e SIGSTOP.

```txt
SIGINT (2): Interrupt - Inviato quando l'utente preme Ctrl+C
SIGKILL (9): Kill - Termina un processo in modo forzato; non può essere catturato o ignorato
SIGSEGV (11): Segmentation Fault - Indica che un processo ha tentato di accedere a una memoria non valida
SIGTERM (15): Terminate - Richiesta di terminare un processo; può essere catturato e gestito dal processo
```

## top e ps

Mentre il primo produce un output dinamicamente, il secondo lo fa staticamente.

```bash
 > top
top - 20:24:27 up  9:18,  2 users,  load average: 0,52, 0,68, 0,60
Tasks: 363 total,   1 running, 359 sleeping,   0 stopped,   3 zombie
%Cpu(s):  2,2 us,  2,2 sy,  0,0 ni, 95,7 id,  0,0 wa,  0,0 hi,  0,0 si,  0,0 st
MiB Mem :  30036,5 total,  13939,2 free,   6648,3 used,  10742,6 buff/cache
MiB Swap:    980,0 total,    980,0 free,      0,0 used.  23388,2 avail Mem

    PID USER      PR  NI    VIRT    RES    SHR S  %CPU  %MEM     TIME+ COMMAND
  46892 dado      20   0   10428   5484   3308 R   8,3   0,0   0:00.02 top
      1 root      20   0   24688  15564  10476 S   0,0   0,1   0:04.42 systemd
      2 root      20   0       0      0      0 S   0,0   0,0   0:00.02 kthreadd
```

`top` consente alcune interazioni:

- `M`: ordina per utilizzo della memoria
- `N`: ordina per *numero* ID del processo
- `T`: *tempo* di esecuzione
- `P`: percentuale di uso della CPU
- `R`: ordine ascendente/discendente
- `k`: termina un processo
- `r`: *renice*, ossia cambia la priorita' di un processo. `top` chiedera' il valore di `nice`, compreso tra -20 e 19 (solo root puo' impostare il valore a un numero negativo o inferiore a quello attuale). Maggiore il valore, minore la priorita'.
- `u`: elenca i processi di un particolare utente
- `c`: mostra i percorsi assoluti dei programmi e distingue tra processi in *userspace* e in *kernel space*  (tra parentesi `[]`) 
- `V`: vista a foresta
- `W`: salva le impostazioni di configurazione in `~/.toprc`

### Output di top

Suddiviso in:

- *summary area*
- *task area*

#### Summary area

Composta dalle cinque righe superiori:

```bash
top - 20:32:32 up  9:27,  2 users,  load average: 0,90, 0,88, 0,73
```
- *current time* (nel formato 24 ore): `20:32:32`
- *uptime*: `up  9:27`
- *numero di utenti attivi* e *carico medio della CPU* per gli ultimi 1, 5, 15 minuti: `2 users,  load average: 0,90, 0,88, 0,73`

```bash
Tasks: 370 total,   1 running, 366 sleeping,   0 stopped,   3 zombie
```
- *numero di processi*: `Tasks: 370 total`
- *processi running*: `1 running`
- *sleeping* (processi in attesa di riprendere l'esecuzione): `366 sleeping`
- *zombie*: quelli che hanno terminato l'esecuzione, ma stanno aspettando che il loro processo padre li rimuova dalla tabella dei processi

```bash
%Cpu(s):  2,2 us,  4,3 sy,  0,0 ni, 93,5 id,  0,0 wa,  0,0 hi,  0,0 si,  0,0 st
```

- *processi utente*: `2,2 us`
- *processi system/kernel*: `4,3 sy` 
- *processi impostati tramite un valore di nice*: `0,0 ni`
- *tempo di inattivita' della CPU*: `93,5 id`
- *processi in attesa di operazioni di I/O*: `0,0 wa`
- *processi che servono interrupt hardware* (periferiche che inviano segnali al processore e che richiedono attenzione): `0,0 hi`
- *processi che servono interrupt software*: `0,0 si`
- *processi che servono le attivita' di VM*: `0,0 st`

```bash
MiB Mem :  30036,5 total,  11781,4 free,   7221,2 used,  12340,0 buff/cache
```

- memoria totale: `Mem :  30036,5 total`
- memoria inutilizzata: ` 11781,4 free`
- memoria in uso: `7221,2 used`
- memoria bufferizzata e memorizzata nella cache, per evitare un accesso eccessivo al disco: `12340,0 buff/cache`

```bash
MiB Swap:    980,0 total,    980,0 free,      0,0 used.  22815,3 avail Mem
```

- swap totale: `Swap:    980,0 total`
- spazio di swap inutilizzato: `980,0 free`
- spazio di swap in uso

#### Task area: campi e colonne

```bash
    PID USER      PR  NI    VIRT    RES    SHR S  %CPU  %MEM     TIME+ COMMAND
  49342 dado      20   0   10428   5492   3316 R   9,1   0,0   0:00.02 top
      1 root      20   0   24688  15564  10476 S   0,0   0,1   0:04.48 systemd
```

Include una serie di campi e colonne che riportano informazioni sui processi in esecuzione:

- `PID`
- `USER`: utente che ha eseguito il comando che ha generato il processo
- `PR`: priorita' del processo al kernel
- `NI`: valore di *nice*
- `VIRT`: memoria totale usata dal processo, incluso lo swap
- `RES`: memoria RAM utilizzata dal processo
- `SHR`: memoria condivisa con altri processi
- `S`: stato del processo. I valori includono S (sleep), R (running) e Z (zombie)
- `%CPU`: percentuale di CPU utilizzata dal processo
- `%MEM`: percentuale di memoria RAM utilizzata (RES in %)
- `TIME+`: tempo totale di attivita' del processo
- `COMMAND`: comando che ha generato il processo

## ps

Mostra un'istantanea dei processi. Per vedere tutti i processi:

```bash
 > ps a
    PID TTY      STAT   TIME COMMAND
   2230 tty1     Ssl+   4:29 sway
   3431 tty1     Sl+    2:26 Xwayland :0 -rootless -core -terminate 10 -listenfd 26 -listenfd 32 -displayfd 106 -wm
  29065 tty1     S+     0:00 swaybg
  29067 tty1     Sl+    0:17 waybar -b bar-0
  49590 pts/1    Ss     0:00 /bin/bash
  49596 pts/1    R+     0:00 ps a
```

`ps` accetta tre diversi stili di opzioni: BSD (ps a), UNIX (ps -a) e GNU (ps --pid).

Per vedere i processi di un particolare utente:

- `ps U user` (BSD)
- `ps -u user` (UNIX)
- `ps --user user` (GNU)

Un comando utile, che produce un output simile a quello di top, che mostra i processi di tutte le shell, e' `ps aux`, dove:

- `a`: mostra tutti i processi collegati a un terminale 
- `u`: formato orientato all'utente
- `x`: mostra i processi che non sono collegati a un terminale

```bash
 > ps aux
'USER         PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
root           1  0.0  0.0  24688 15564 ?        Ss   11:05   0:04 /sbin/init
root           2  0.0  0.0      0     0 ?        S    11:05   0:00 [kthreadd]
root           3  0.0  0.0      0     0 ?        S    11:05   0:00 [pool_workqueue_release]
```

- `USER`
- `PID`
- `%CPU`: percentuale di CPU utilizzata
- `%MEM`: percentuale di memoria fisica utilizzata
- `TT`: terminale (*tty*) che controlla il processo
- `STAT`: codice che rappresenta lo stato del processo. I valori includono S (sleep), R (running), Z (zombie), T (stopped)
- `STARTED`: ora in cui e' iniziato il processo

## killall

```bash
killall [OPTIONS] process-name
```
Opzioni principali:

- `-e`: richiede una corrispondenza esatta per il nome del processo
- `-I`: esegue la ricerca dei nomi dei processi in modo insensibile alle maiuscole e minuscole
- `-i`: richiede conferma interattiva prima di uccidere i processi

```bash
killall -i htop
```

- `-r`: permette l'utilizzo di un'espressione regolare

```bash
kill -r REGEX
killall -r 'http.*'
```

- `-s SIGNAL`: Specifica il segnale da inviare per terminare i processi (predefinito è SIGTERM)

```bash
killall -s <Termination_Signal> process
killall -s SIGKILL apache2
```

- `-u USER`: uccide i processi di proprietà dell'utente specificato

```bash
sudo killall -u <username> process
sudo killall -u team htop
```