|
@@ -0,0 +1,111 @@
|
|
|
+# Piattaforme e Software per la rete - lezione 2
|
|
|
+#### William Fornaciari
|
|
|
+###### 10 March 2016
|
|
|
+## Processi - Concetti di base
|
|
|
+
|
|
|
+### Esecuzione sequenziale (senza s.o.)
|
|
|
+I sistemi tradizionali adottano l'__esecuzione sequenziale__,
|
|
|
+possibile adottarla su ogni core per sistemi multicore.
|
|
|
+Questa soluzione presenta diversi vantaggi
|
|
|
+- Semplicità e facilità di debug
|
|
|
+- Determinismo della sequenza e dei tempi di esecuzione
|
|
|
+
|
|
|
+Ma anche degli svantaggi
|
|
|
+- Accesso di un solo utente alla volta
|
|
|
+- Esecuzione di un solo programma alla volta
|
|
|
+- Scarso sfruttamento delle risorse hardware
|
|
|
+
|
|
|
+### Esecuzione Parallela (con s.o.)
|
|
|
+Parallelismo *simulato* se ho un solo processore, *reale* se ho cpu multiple
|
|
|
+Introduce alcuni problemi:
|
|
|
+- Il determinismo non è garantito automaticamente
|
|
|
+- L'ordine di esecuzione non è fissato
|
|
|
+- Conflitti di accesso alle risorse
|
|
|
+Questi problemi sono risolti dal Sistema Operativo
|
|
|
+- Scheduling, memoria virtuale, periferiche virtuali...
|
|
|
+- Gestione di processi, sincronizzazione...
|
|
|
+
|
|
|
+### Processo
|
|
|
+Di solito i processi vengono eseguiti su un sistema operativo.
|
|
|
+Ma è possibile eseguire degli scheduler direttamente sul ferro
|
|
|
+ e far eseguire agli scheduler il proprio processo (es: rtx)
|
|
|
+vedi esecuzione sequenziale
|
|
|
+
|
|
|
+#### Nota
|
|
|
+I processori per sistemi embedded (es: STM32) costano da qualche centesimo a qualche €, e
|
|
|
+dispongono di una memoria di qualche KB, quindi è utile risparmiare memoria, ad es.
|
|
|
+ evitando di usare un sistema operativo.
|
|
|
+
|
|
|
+Ogni processo è identificato da un PID (Process IDentifier) univoco e viene creato
|
|
|
+da un processo *padre*
|
|
|
+Unica eccezione è il processo __init__ che è il primo ad essere eseguito
|
|
|
+
|
|
|
+### Gerarchia di processi
|
|
|
+
|
|
|
+Nei sistemi embedded non serve il paradigma di avvio tradizionale linux
|
|
|
+init -> login -> shell -> processo
|
|
|
+Può essere lanciato direttamente il processo principale del sistema.
|
|
|
+
|
|
|
+### Modello di memoria
|
|
|
+__Memoria virtuale__ viene mappata sulla memoria disica dal sistema operativo
|
|
|
+mediante il PD (Process Descriptor)
|
|
|
+Questo da più flessibilità perchè evito frammentazione in memoria, permette di far andare
|
|
|
+uno stesso programma su hardware diversi, di questo si occupa la MMU.
|
|
|
+Nei sistemi embedded non c'è MMU e non viene usata memoria virtuale.
|
|
|
+Memoria organizzata in __segmenti__
|
|
|
+
|
|
|
+### Operazioni sui processi
|
|
|
+- Creazione di un processo:
|
|
|
+ - `fork()` crea una copia del processo padre con la sola eccezione del PID,
|
|
|
+il figlio condivide il codice del padre, ha la parde dati copiata ma ha un suo Process Descriptor.
|
|
|
+ - Lo spreco di memoria legato alla copia della sezione dati può essere evitato con
|
|
|
+una `vfork()` o una `fork()` che implementa copy on write.
|
|
|
+
|
|
|
+- Terminazione di un processo
|
|
|
+ - con la `exit(int status)` viene salvato il valore di stato nel Process Descriptor,
|
|
|
+e viene segnalata la terminazione del figlio inviando una `SIGCHLD` al padre.
|
|
|
+
|
|
|
+- Attendere la terminazione di un processo
|
|
|
+ - `wait()` Se viene eseguita prima della terminazione del ciclo viene aspettata la terminazione
|
|
|
+del figlio, se viene eseguida dopo la terminazione, il figlio diventa un processo zombie.
|
|
|
+ - Stato di terminazione viene passato nella parte significativa per
|
|
|
+stato normale `es: 0x2000`, nella parte meno significativa per codici di errore `es: 0x0009`
|
|
|
+è una cosa sporca ma è stata pensata tanti anni fa.
|
|
|
+
|
|
|
+- Sostituire il codice di un processo
|
|
|
+ - `exec()` Segmenti TEXT e DATA sostituiti ma stesso PID e file/socket aperti rimangono.
|
|
|
+Ci sono vari tipi di exec che sono frontend di `execve()`
|
|
|
+
|
|
|
+Esempio
|
|
|
+```
|
|
|
+if((pid2 = fork()) == 0)
|
|
|
+ execv("editor", argv);
|
|
|
+```
|
|
|
+
|
|
|
+- Segnalazione di eventi
|
|
|
+Un processo *orphaned* è quando il padre termina prima che termini il figlio, quando il figlio
|
|
|
+termina, viene adottato dal processo init (parent PID settato a 1 nel PD).
|
|
|
+
|
|
|
+### Inizializzazione e terminazione di un programma
|
|
|
+La funziona `_exit()` rappresenta l'ultima operazione eseguita dalla `exit()` che invece effettua
|
|
|
+ tutte le operazioni di housekeeping, che possono anche essere personalizzate utilizzando
|
|
|
+ le primitive `atexit(void(*f) (void));` e se ne possono registrare fino a 32.
|
|
|
+
|
|
|
+La terminazione di un programma avviene sempre mediante un segnale
|
|
|
+- Ricevuto dal processo
|
|
|
+- Generato dal processo tramite `abort()`, che invia un segnale a se stesso per
|
|
|
+ funzionare in modo analogo alla prima opzione.
|
|
|
+
|
|
|
+I segnali possono essere inviati tramite la funzione `kill()` (nome fuorviante)
|
|
|
+Il più delle volte la signal implica la chiusura del processo, a volte viene effettuato un core dump
|
|
|
+cioè un salvataggio dello stato del sistema utile per debuggare.
|
|
|
+Si può registrare un handler per una signal, altrimenti utilizza il comportamento di default,
|
|
|
+ ad esempio CTRL+C agisce da signal non registrata e quindi come effetto chiude 'applicazione.
|
|
|
+La funzione `raise()` invia un segnale a processo stesso.
|
|
|
+Nel caso si riceva un segnale è possibile
|
|
|
+- Ignorare il segnale, tranne SIGKILL e SIGSTOP es:`h = signal(SIGINT,SIG_IGN );`
|
|
|
+- Effettuare una operazione specificata tramite un signal handler `sighandler_t signal(int signum, sighandler_t,...)`
|
|
|
+`alarm()` imposta un timer che alla scadenza invierà un SIGALRM al processo,
|
|
|
+può essere combinata con un handler e pause per fare un timeout o altri barbatrucchi.
|
|
|
+
|
|
|
+
|