Definizione: processo

Il processo รจ unโ€™istanza di un programma in esecuzione su un computer e rappresenta una delle unitร  fondamentali di gestione delle risorse da parte di un sistema operativo. Quando un programma viene eseguito, il sistema operativo crea un processo per esso, fornendogli le risorse necessarie, come CPU, memoria, accesso ai file e altri dispositivi.

Osservazione: differenza tra processo e programma

La differenza tra il concetto di processo e quello di programma รจ fondamentale in informatica, poichรฉ indicano concetti distinti legati allโ€™esecuzione di unโ€™applicazione:

  • Un programma รจ un insieme di istruzioni scritte in un linguaggio di programmazione, che descrive quali operazioni un computer deve eseguire. รˆ unโ€™entitร  passiva e rappresenta il codice sorgente o il codice binario di unโ€™applicazione, che viene memorizzato in un file su disco (es. un file eseguibile .exe su Windows, oppure un documento contenente codice sorgente scritto in un linguaggio di programmazione come Python o C). Un programma non fa nulla da solo finchรฉ non viene avviato.
  • Un processo รจ unโ€™istanza di un programma in esecuzione sulla memoria centrale (RAM). รˆ unโ€™entitร  attiva che include il codice del programma, lo stato della CPU (come il contatore del programma e i registri), lo spazio di memoria (segmento di testo e dei dati, stack e heap) e le risorse utilizzate dal programma. Quando un programma viene eseguito, il sistema operativo crea un processo per gestirne lโ€™esecuzione.

Ecco una tabella riassuntiva:

CaratteristicaProgrammaProcesso
DefinizioneUn insieme di istruzioni memorizzate su discoUnโ€™istanza di un programma in esecuzione
StatoEntitร  passivaEntitร  attiva
MemoriaNon usa memoria attivaUtilizza memoria (segmento di testo e dei dati, stack e heap)
EsecuzioneNon รจ in esecuzioneIn esecuzione
DurataPermanente fino a quando รจ cancellato o modificatoTemporanea, esiste solo durante lโ€™esecuzione
GestioneNon richiede gestione attivaGestito dal sistema operativo (CPU, memoria, I/O)
RelazioneUn programma puรฒ generare piรน processiOgni processo รจ basato su un programma

Osservazione: piรน processi per lo stesso programma

Sebbene due processi siano associabili allo stesso programma, sono tuttavia da considerare due sequenze dโ€™esecuzione distinte. Per esempio, lโ€™utente puรฒ aprire piรน finestre dello stesso browser e, di conseguenza, generare piรน istanze dello stesso programma: ciascuna istanza รจ un diverso processo e, benchรฉ le sezioni di memoria contenenti il codice siano equivalenti, in realtร  quelle dei dati, dellโ€™heap e dello stack sono diverse. รˆ inoltre usuale che durante la propria esecuzione un processo generi altri processi.

1 - Il PCB e le informazioni sul processo

Definizione: blocco di controllo del processo (PCB)

Il blocco di controllo del processo (in inglese PCB, Process Control Block) รจ una struttura dati fondamentale utilizzata dal sistema operativo per memorizzare nella RAM tutte le informazioni relative a un processo dal momento della sua inizializzazione e aggiornato durante lโ€™intero ciclo di vita del processo.

Le informazioni contenute in un PCB variano a seconda delle implementazioni nei vari sistemi operativi, ma in generale sono presenti:

  • Stato del processo: la condizione in cui si trova un processo in un dato momento durante la sua esecuzione nel sistema operativo (new, ready, running, waiting o terminated).
  • Identificatore del processo (in inglese PID, Process ID): un numero intero univoco assegnato al processo dal sistema operativo. Questo identificatore viene utilizzato per distinguere il processo dagli altri processi attivi.
  • Program Counter (abbreviato in PC): il valore contenuto nel Program Counter della CPU nel momento in cui il processo รจ stato interrotto, per consentire di riprendere poi lโ€™esecuzione correttamente dallโ€™ultima istruzione eseguita prima dellโ€™interruzione stessa. Non viene aggiornato di continuo, ma solo nel momento in cui si effettua il cambio di contesto, perchรฉ altrimenti sarebbe inutile e poco efficiente tenerlo sincronizzato.
  • Stato dei registri della CPU: i valori contenuti in alcuni registri della CPU di uso comune (es. accumulatori, puntatori allo stack, registri di uso generale) nel momento in cui il processo รจ stato interrotto. Come per il Program Counter, non vengono aggiornati di continuo, ma solo nel momento in cui si effettua il cambio di contesto, perchรฉ altrimenti sarebbe inutile e poco efficiente tenere tutti i valori sincronizzati.
  • Informazioni sulla gestione della memoria: dati su come la memoria รจ allocata al processo, come indirizzi di base e limiti di memoria del processo, oppure tabelle di paginazione o segmentazione, nel caso il sistema operativo utilizzi tecniche di gestione della memoria virtuale.
  • Informazioni di I/O: un elenco dei dispositivi di input/output utilizzati dal processo (es. file aperti, dispositivi hardware come stampanti, reti) e file descriptor che fanno riferimento ai file aperti dal processo.
  • Informazioni di schedulazione: un elenco delle informazioni utili alla schedulazione dei processi, come:
    • Prioritร  del processo: indica lโ€™importanza relativa del processo rispetto agli altri.
    • Tempo di esecuzione accumulato: il tempo che il processo ha trascorso in esecuzione.
    • Algoritmo di schedulazione utilizzato: se il sistema operativo utilizza diverse politiche di schedulazione, nel PCB viene specificata quale viene usata.
  • Informazioni di accounting: dati utilizzati per tenere traccia del tempo CPU consumato dal processo, della quantitร  di risorse utilizzate e di eventuali statistiche di utilizzo, utili per la fatturazione o il monitoraggio delle prestazioni.
  • Informazioni sui segnali: un elenco dei segnali che il processo puรฒ ricevere e le relative azioni da eseguire al ricevimento di un segnale (ad esempio, terminare il processo o ignorare il segnale).

1.1 - Stato di un processo

Definizione: stato di un processo

Lo stato di un processo rappresenta la condizione in cui si trova un processo in un dato momento durante la sua esistenza nel sistema operativo. Serve a gestire i processi in modo efficiente, garantendo che la CPU venga utilizzata in modo ottimale senza che rimanga inattiva: per esempio, quando un processo รจ in attesa, il sistema operativo puรฒ assegnare la CPU a un altro processo giร  pronto per essere eseguito.

Gli stati principali di un processo sono new, ready, running, waiting e terminated.

Attenzione: gli stati potrebbero cambiare nei vari sistemi operativi

A seconda del sistema operativo, i nomi degli stati potrebbero variare o, in alcuni casi, potrebbero esserci ulteriori distinzioni tra i vari stati, oltre ai soliti 5 (new, ready, running, waiting e terminated).

Vediamo ora la definizione completa di ogni stato.

Definizione: stato new (nuovo)

Un processo entra nello stato new (nuovo) non appena viene creato e ci rimane finchรฉ non sarร  pronto per essere eseguito. Durante questa fase di inizializzazione vengono assegnate risorse come memoria e PID.

Definizione: stato ready (pronto)

Un processo entra nello stato ready (pronto) quando รจ pronto per essere eseguito ma sta aspettando che la CPU diventi disponibile perchรฉ รจ occupata da altri processi.

Definizione: stato running (in esecuzione)

Un processo รจ nello stato running (in esecuzione) quando utilizza la CPU e le sue istruzioni vengono eseguite.

Definizione: stato waiting (in attesa)

Un processo รจ nello stato waiting (in attesa) (o anche blocked (bloccato) oppure sleeping (dormiente)) quando รจ in attesa di un evento esterno per continuare lโ€™esecuzione, come il completamento di unโ€™operazione di input/output (I/O), la ricezione di dati o un messaggio.

Definizione: stato terminated (terminato)

Un processo entra nello stato terminated (terminato) quando ha completato la sua esecuzione o รจ stato interrotto in modo anomalo (per esempio, a causa di un errore). In questo stato, tutte le risorse del processo vengono rilasciate e il processo non esiste piรน nel sistema operativo.

1.1.1 - Visualizzazione degli stati correnti dei processi

In UNIX, tramite il comando ps -axjf si puรฒ avere una visualizzazione ad albero della lista di tutti i processi presenti nel sistema (ovverosia presenti nella coda dei processi) e, nella colonna STAT, ogni codice รจ associato a uno stato o una caratteristica del processo ed essi possono essere combinati tra loro:

Codice STATDescrizione
SSleeping: il processo รจ nello stato sleeping e si trova allโ€™interno della coda dei processi bloccati in attesa che accada un evento, come un segnale o che un input diventi disponibile.
RRunning: il processo รจ nello stato running e si trova allโ€™interno della coda dei processi pronti pronto per essere eseguito o giร  in esecuzione.
DDisk sleep: il processo รจ in uno stato sleeping non interrompibile e si trova allโ€™interno della coda dei processi bloccati in attesa che un input o output diventi disponibile.
TStopped: il processo รจ nello stato blocked, messo in pausa da un segnale.
ZZombie: il processo รจ nello stato zombie, ossia รจ terminato ma รจ in attesa di una wait() dal processo padre.
NNice: il processo รจ in esecuzione con bassa prioritร .
WWaiting for paging: il processo รจ in attesa che le pagine di memoria vengano scritte o lette dal disco (raro nei moderni sistemi Linux).
sSession leader: il processo รจ un leader di sessione (es. una shell che avvia altri processi).
+Il processo appartiene al gruppo di processi in esecuzione in primo piano (foreground) nel terminale.
lIl processo รจ multithreaded (usato su alcuni sistemi come Solaris e Linux).
<Il processo ha una prioritร  alta, quindi riceve piรน CPU rispetto ad altri.

1.2 - Identificatore del processo (PID)

Definizione: identificatore del processo (PID)

Lโ€™identificatore del processo (in inglese PID, Process ID) รจ un numero intero univoco assegnato al processo dal sistema operativo. Questo identificatore viene utilizzato per distinguere il processo dagli altri processi attivi allโ€™interno del kernel.

1.2.1 - Ottenere i PID tramite getpid() e getppid()

La funzione getpid() รจ una chiamata di sistema utilizzata per ottenere il PID del processo che la usa.

Il suo prototipo รจ il seguente:

#include <unistd.h>
 
pid_t getpid();

dove:

  • pid_t restituito: PID del processo che ha invocato la funzione.

La funzione getppid() รจ una chiamata di sistema utilizzata per ottenere il PID del processo padre di quello che la usa.

Il suo prototipo รจ il seguente:

#include <unistd.h>
 
ppid_t getppid();

dove:

  • ppid_t restituito: PID del processo padre del processo che ha invocato la funzione.

Le relazioni tra processi costituiscono una struttura ad albero. Il genitore di ogni processo ha a sua volta un genitore, fino ad arrivare alla radice: il processo init.

1.3 - Spazio di memoria

Definizione: spazio di memoria di un processo

Lo spazio di memoria di un processo rappresenta lโ€™insieme di tutte le aree di memoria allocate per un processo dal sistema operativo e contiene il codice eseguibile, i dati e le strutture necessarie per far funzionare il programma. Ogni processo ha il proprio spazio di memoria isolato, separato da quello degli altri processi, garantendo che un processo non possa accedere o modificare direttamente la memoria di un altro processo: questa separazione migliora la sicurezza e la stabilitร  del sistema.

Lo spazio di memoria di un processo รจ solitamente diviso in:

  1. Segmento di codice (o segmento testo): contiene il codice eseguibile del programma, cioรจ le istruzioni che la CPU eseguirร . Il segmento di codice รจ generalmente di sola lettura, per evitare che il codice del programma venga accidentalmente modificato.
  2. Segmento dati: contiene le variabili globali e statiche del programma, divise in:
  • Dati inizializzati: lโ€™insieme delle variabili globali e statiche a cui รจ stato assegnato un valore al momento della dichiarazione.
  • Dati non inizializzati (in inglese BSS, Block Started by Symbol): lโ€™insieme delle variabili globali e statiche che sono dichiarate ma non esplicitamente inizializzate, quindi non hanno un valore inizialmente definito; in alcuni sistemi operativi vengono inizializzate a zero.
  1. Heap: รจ lโ€™area della memoria dinamica utilizzata per lโ€™allocazione di memoria a runtime. Quando un programma richiede memoria dinamica (ad esempio tramite funzioni come malloc() in C o new in C++/Java), questa viene allocata nello heap, il quale viene gestito unicamente dal programmatore stesso (cioรจ il programmatore รจ lโ€™unico responsabile della gestione e del rilascio della memoria).

  2. Stack: area di memoria che viene utilizzata per memorizzare variabili locali, parametri di funzione e indirizzi di ritorno da funzioni. Ogni volta che viene chiamata una funzione, un nuovo โ€œframeโ€ viene aggiunto allo stack, che contiene le informazioni relative a quella particolare chiamata. Quando la funzione termina, lo stack viene โ€œsrotolatoโ€ e il frame della funzione viene rimosso. Lo stack si espande e si contrae automaticamente durante lโ€™esecuzione del programma, e la sua gestione รจ di solito curata dal compilatore e dal sistema operativo.

Ecco una rappresentazione grafica dello spazio di memoria di un processo:

Spazio di memoria di un processo.png

1.3.1 - Variazione della grandezza dei segmenti di memoria

Si puรฒ notare che le dimensioni dei segmenti di codice e di dati sono fisse, ovvero non cambiano durante lโ€™esecuzione del programma, mentre le dimensioni di stack e heap possono ridursi e crescere dinamicamente durante lโ€™esecuzione:

  • Ogni volta che si chiama una funzione, viene inserito nello stack una struttura dati detta record di attivazione (in inglese activation record) contenente i suoi parametri, le variabili locali e lโ€™indirizzo di ritorno; quando la funzione restituisce il controllo al chiamante, il record di attivazione viene rimosso dallo stack.
  • Allo stesso modo, lโ€™heap crescerร  quando viene allocata memoria dinamicamente e si ridurrร  quando la memoria viene restituita al sistema.

Visto che le sezioni dello stack e dellโ€™heap crescono lโ€™una verso lโ€™altra, tocca al sistema operativo garantire che non si sovrappongano.

5 - Concorrenza tra processi

In informatica, la concorrenza รจ la proprietร  di un sistema in cui piรน attivitร  indipendenti fanno progresso nello stesso intervallo di tempo, condividendo potenzialmente risorse, senza che sia richiesta la loro esecuzione simultanea.

  • Un singolo processore puรฒ gestire concorrenza tramite interleaving (alternanza rapida tra task).
  • Lโ€™obiettivo principale รจ la gestione di piรน compiti (reattivitร , organizzazione, correttezza).

Esempio Un sistema operativo con un solo core che alterna:

  • un editor di testo
  • un browser
  • un processo in background

I processi sono concorrenti, ma non paralleli.

Osservazione:

  • Un sistema puรฒ essere concorrente ma non parallelo.
  • Un sistema parallelo รจ sempre anche concorrente (ma non viceversa).

5.1 - Parallelismo

Uno dei modi in cui si puรฒ implementare la concorrenza รจ col parallelismo, ossia eseguendo piรน unitร  di elaborazione contemporaneamente.

Definizione: parallelismo

Il parallelismo รจ la capacitร  di eseguire piรน processi o thread contemporaneamente. Questo viene gestito dal sistema operativo attraverso tecniche come il multiprocessing e il multithreading. Il parallelismo nei sistemi operativi consente un migliore utilizzo delle risorse della CPU e migliora la reattivitร  delle applicazioni.

Definizione: legge di Amdahl

La legge di Amdahl afferma che seย ย รจ la frazione di un calcolo che รจ parallelizzabile (cioรจ che puรฒ beneficiare dal parallelismo), e รจ la frazione che non puรฒ essere parallelizzata, allora lโ€™aumento massimo di velocitร , cioรจ lโ€™accelerazione , che si puรฒ ottenere usandoย ย processori รจ:

Al tendere del numeroย ย di processori allโ€™infinito, lโ€™accelerazione tende a (perchรฉ tende a ). In pratica, il rapporto prestazioni/prezzo scende rapidamente al crescere diย , dato cheย ย diventa piccolo rispetto aย .

Osservazione: quando usare il parallelismo

Dalla legge di Amdahl si puรฒ intuire che il parallelismo รจ utile solamente o per piccoli numeri diย processoriย o per problemi con valori molto bassi diย . Per fare un esempio, seย ย รจ solamente il (cioรจ solo un decimo delle operazioni non sono parallelizzabili), la velocitร  del calcolo puรฒ essere al massimo decuplicata, indipendentemente dal valore diย .

Tipi di parallelismo

Parallelismo dei dati: distribuisce sottoinsiemi degli stessi dati su piรน processi, stessa operazione su ognuno di essi

Esempio: Si consideri, per esempio, lโ€™operazione di somma dei valori contenuti in un vettore di dimensione N. In un sistema con un singolo core, un thread sommerebbe semplicemente gli elementi da [0] a [N โ€“ 1]. In un sistema dual-core, invece, il thread A, in esecuzione sul core 0, potrebbe sommare gli elementi da [0] a [N/2 โ€“ 1], mentre il thread B, in esecuzione sul core 1, potrebbe sommare gli elementi da [N/2] a [N โ€“ 1]. I due thread sarebbero in esecuzione in parallelo su core di elaborazione distinti.

Parallelismo delle attivitร : distribuisce le attivitร  sui core, ognuno dei quali effettua operazioni distinte sugli stessi dati degli altri o su dati diversi.

Esempio: A differenza della situazione precedente, un esempio di parallelismo delle attivitร  potrebbe coinvolgere due thread, ciascuno dei quali esegue unโ€™unica operazione statistica sullโ€™array di elementi. I thread operano ancora in parallelo su core separati, ma ciascuno sta eseguendo unโ€™operazione diversa

Tuttavia, parallelismo dei dati e parallelismo delle attivitร  non sono mutuamente esclusivi, e le applicazioni possono utilizzare un ibrido di queste due strategie.

5.1.1 - Multiprocessing

Definizione: multiprocessing

Il multiprocessing รจ la capacitร  di un sistema operativo di implementare il parallelismo tra processi, eseguendoli simultaneamente, ciascuno con il proprio spazio di memoria, consentendo un isolamento e una stabilitร  piรน robusti.

Multiprogrammazione

Definizione: multiprogrammazione

La multiprogrammazione รจ una tecnica dei sistemi operativi che consente di mantenere piรน processi in memoria centrale contemporaneamente, alternandone lโ€™esecuzione sulla CPU.

Lโ€™idea di base รจ evitare che la CPU rimanga inattiva: quando un processo in esecuzione si blocca (ad esempio per unโ€™operazione di I/O), il sistema operativo assegna la CPU a un altro processo pronto. In questo modo si massimizza lโ€™utilizzo del processore e si migliora lโ€™efficienza complessiva del sistema.

รˆ opportuno distinguere la multiprogrammazione da concetti affini:

  • Multitasking: spesso usato come sinonimo a livello pratico, ma enfatizza lโ€™alternanza rapida dei processi per garantire reattivitร  allโ€™utente;
  • Multiprocessing: prevede piรน CPU o core che eseguono processi realmente in parallelo;
  • Multithreading: riguarda la presenza di piรน thread allโ€™interno dello stesso processo, non piรน processi distinti.

5.2 - Multitasking

Definizione: multitasking

Il multitasking รจ la capacitร  di un sistema operativo di eseguire piรน processi in maniera apparentemente simultanea, cioรจ eseguendoli in modo sequenziale con rapidi cambi di contesto che danno allโ€™utente lโ€™impressione che tutti stiano avanzando contemporaneamente.

I principali vantaggi del multitasking sono:

  • Miglior utilizzo della CPU: sfrutta al massimo la capacitร  del processore eseguendo diverse attivitร , riducendo i tempi di inattivitร  della CPU.
  • Efficienza e produttivitร : permette di eseguire piรน operazioni allo stesso tempo, migliorando la produttivitร , ad esempio facendo girare un programma in background mentre si lavora su un altro.
  • Esperienza utente migliorata: in applicazioni con interfaccia grafica (GUI), il multitasking permette agli utenti di continuare a utilizzare lโ€™applicazione mentre altre operazioni vengono completate in background, mantenendo la reattivitร .
  • Condivisione delle risorse: i processi possono condividere risorse come la memoria, riducendo il consumo complessivo e ottimizzando lโ€™uso delle risorse di sistema.
  • Flessibilitร : facilita lโ€™esecuzione di diversi tipi di attivitร  su un unico dispositivo, come navigare su internet mentre si ascolta musica o si scaricano file.

I principali svantaggi del multitasking sono:

  • Overhead del sistema: cambiare rapidamente da un processo allโ€™altro (ossia effettuare un cambio di contesto) richiede risorse di sistema e puรฒ rallentare le prestazioni generali.
  • Rischio di collisione: con piรน processi che accedono alle stesse risorse, come la memoria, puรฒ essere necessario gestire i conflitti di risorse e sincronizzare i processi, aumentando la complessitร .
  • Maggiore complessitร  e possibilitร  di errori: la gestione di piรน processi o thread richiede un controllo avanzato e puรฒ portare a errori difficili da identificare, come deadlock o race conditions.
  • Riduzione delle prestazioni su sistemi limitati: su sistemi con meno risorse, il multitasking puรฒ ridurre lโ€™efficienza complessiva, creando un sovraccarico che rallenta il sistema.
  • Problemi di sicurezza: se i processi non sono ben isolati, un processo puรฒ influenzare o interferire con altri, creando vulnerabilitร  e rischi per la sicurezza.

6 - Processo init in UNIX

In UNIX, il processo init รจ il primo processo che il kernel manda in esecuzione dopo che il computer ha terminato la fase di bootstrap ed รจ il processo padre di tutti gli altri processi del sistema. Si occupa dellโ€™inizializzazione del sistema, della gestione degli stati di avvio e dello spegnimento del sistema e ha tipicamente PID 1.

Fonti

  • Abraham Silberschatz, Peter Baer Galvin, Greg Gagne - Sistemi Operativi (10แตƒ Edizione) - Pearson, 2019 - ISBN: 9788891904560.
    • Capitolo 3: processi
    • Capitolo 4: thread
    • Capitolo 5: schedulazione della CPU
  • ๐Ÿซ Lezioni e slide del Prof. Aldinucci Marco del corso di Sistemi Operativi (canale B), Corso di Laurea in Informatica presso lโ€™Universitร  di Torino, A.A. 2024-25:
  • ๐Ÿซ Lezioni e slide del Prof. Schifanella Claudio del corso di Laboratorio di Sistemi Operativi (canale B, turno T4), Corso di Laurea in Informatica presso lโ€™Universitร  di Torino, A.A. 2024-25:
  • ๐Ÿซ Appunti di Carlos Palomino del corso di Sistemi Operativi, Corso di Laurea in Informatica presso lโ€™Universitร  di Torino, A.A. 2024-25 (caricati sul repository GitHub del Team Studentesco Informatica):