Processi

Riassunto IA

Un processo è un'entità attiva in esecuzione dotata di risorse proprie, gestita dal sistema operativo tramite un Process Control Block (PCB) che ne traccia lo stato e il contesto. Mentre nei sistemi single-core la concorrenza è simulata tramite time slicing, le architetture multicore abilitano il parallelismo reale distribuendo i thread del processo su unità di calcolo fisicamente indipendenti.

Immagine generata con IA
Immagine generata con IA

Introduzione

In questo articolo approfondiamo l'architettura dei processi all'interno dei sistemi operativi, distinguendo tra il concetto di programma statico e quello di entità attiva in esecuzione.

Che cos'è un processo?

Un processo è definito come un programma in esecuzione: un’entità attiva dotata di un contatore di programma e di un insieme di risorse associate. Si distingue dal programma, che è invece un’entità passiva, ad esempio un file memorizzato su disco.

In memoria, un processo è suddiviso in sezioni specifiche:

  • Testo (Text Segment): contiene il codice eseguibile.
  • Dati (Data Segment): contiene le variabili globali e statiche.
  • Heap: area di memoria allocata dinamicamente durante l’esecuzione.
  • Stack: memoria temporanea utilizzata per le chiamate di funzione e le variabili locali.

Nei sistemi moderni il concetto si estende ai thread., che consentono a un singolo processo di avere più percorsi di esecuzione concorrenti, facilitando il parallelismo nei sistemi multicore.

Il core e il multicore

Un core è un’unità di calcolo fisica indipendente all’interno della CPU.

Una CPU contiene tipicamente:

  • Registri
  • ALU (Arithmetic Logic Unit)
  • Logica di controllo
  • Capacità di eseguire un flusso di istruzioni indipendente

Fino ai primi anni 2000, le CPU disponevano generalmente di un solo core. Ciò significava che poteva essere eseguita una sola istruzione alla volta per ciascun ciclo di clock.

Il sistema operativo utilizzava il time slicing, una tecnica che assegna a ciascun processo un intervallo di tempo limitato di utilizzo della CPU (time slice). Ad esempio:

  • Processo A per 5 ms
  • Processo B per 5 ms
  • Processo C per 5 ms
  • Ritorno al processo A

Il cambio tra processi (context switch) avviene così rapidamente da risultare impercettibile all’utente. Tuttavia, il core esegue comunque una sola istruzione per volta: il parallelismo è simulato.

In un sistema multicore, invece, esistono più core fisici. Di conseguenza:

  • Il core 1 può eseguire il thread A
  • Il core 2 può eseguire il thread B
  • Il core 3 può eseguire il thread C

Tutto nello stesso istante fisico. In questo caso il parallelismo è reale, non simulato.

Un processo può avere più thread. Ogni thread:

  • È un percorso di esecuzione indipendente
  • Possiede un proprio program counter
  • Ha un proprio stack
  • Condivide l’heap e le risorse del processo con gli altri thread

Ad esempio, con un processo composto da 4 thread e una CPU a 4 core, il sistema operativo può assegnare un thread a ciascun core, eseguendo il programma in parallelo su più unità fisiche.

Stato e controllo del processo

Ogni processo attraversa diversi stati durante il suo ciclo di vita: nuovo, pronto, esecuzione, attesa e terminato.

Il sistema operativo rappresenta ogni processo tramite un PCB (Process Control Block), che memorizza informazioni cruciali quali:

  • Stato corrente
  • PID (Process Identifier)
  • Contatore di programma
  • Registri della CPU
  • Informazioni di memoria

Il ciclo di vita di un processo

Un processo può trovarsi nei seguenti stati:

  • Nuovo (New): è stato creato ma non è ancora pronto per l’esecuzione.
  • Pronto (Ready): è in memoria e attende l’assegnazione della CPU.
  • Esecuzione (Running): sta utilizzando la CPU.
  • Attesa (Waiting/Blocked): è in attesa di un evento esterno, tipicamente un’operazione di I/O.
  • Terminato (Terminated): ha completato la propria esecuzione.

Questi stati determinano in quale struttura dati del kernel il processo viene inserito e quali operazioni possono essere effettuate su di esso.

Code di scheduling

Il sistema operativo mantiene diverse code:

  • Ready Queue: contiene i processi pronti all’esecuzione.
  • Waiting Queue: contiene i processi in attesa di eventi.
  • Device Queue: una coda per ciascun dispositivo di I/O.

Quando un processo richiede un’operazione di I/O:

  1. Viene spostato nella coda del dispositivo.
  2. Il kernel assegna la CPU a un altro processo pronto.
  3. Al termine dell’I/O (tramite interrupt), il processo torna nella ready queue.

Il Process Control Block (PCB)

Il PCB è la struttura dati con cui il kernel rappresenta un processo.

Contiene:

  • Stato del processo
  • PID
  • Program counter
  • Registri della CPU
  • Informazioni di scheduling (priorità, puntatori alle code)
  • Informazioni di memoria (tabelle delle pagine, limiti)
  • File aperti e risorse allocate
  • Informazioni di accounting (tempo di CPU utilizzato)

Il PCB risiede nello spazio kernel ed è accessibile esclusivamente al sistema operativo.

Context switch

Il context switch è il meccanismo con cui il sistema operativo interrompe un processo e ne attiva un altro.

Le operazioni principali sono:

  1. Salvare registri e program counter nel PCB del processo corrente.
  2. Selezionare un processo dalla ready queue.
  3. Ripristinare lo stato del nuovo processo dal suo PCB.

Il context switch rappresenta un overhead inevitabile del multitasking.

Scheduling e politiche decisionali

La scelta del processo successivo dipende dall’algoritmo di scheduling:

  • FCFS (First Come, First Served)
  • SJF (Shortest Job First)
  • Round Robin
  • Priority Scheduling

Ogni algoritmo ottimizza metriche diverse:

  • Tempo medio di attesa
  • Tempo di risposta
  • Throughput
  • Equità

Non esiste una soluzione universalmente ottimale: la scelta dipende dal contesto applicativo.

Stati estesi

Nei sistemi operativi moderni esistono stati aggiuntivi.

Suspended

Indica che il processo è temporaneamente escluso dalla competizione per la CPU.

Può accadere per:

  • Swapping su disco
  • Sospensione amministrativa
  • Politiche di gestione delle risorse

Differenza fondamentale:

  • Waiting: attesa di un evento.
  • Suspended: esclusione per decisione del sistema o gestione della memoria.

Zombie

Un processo zombie ha terminato l’esecuzione ma il suo PCB non è ancora stato rimosso.

Il processo:

  1. Rilascia le risorse.
  2. Conserva nel PCB il codice di uscita.
  3. Attende che il padre invochi wait().

Non consuma CPU, ma occupa una voce nella tabella dei processi.

Orphan

Un processo orfano è un processo il cui padre termina prima di lui.

Nei sistemi Unix-like viene adottato dal processo init (PID 1) o da un suo equivalente, che si occuperà di raccoglierne lo stato finale.

Coordinamento nei sistemi multicore

Nei sistemi multicore:

  • Più CPU eseguono in parallelo.
  • Le strutture dati del kernel sono condivise.
  • Le decisioni di scheduling possono avvenire simultaneamente.

Strutture condivise

  • Ready queue
  • Tabelle dei processi (PCB)
  • Tabelle delle pagine

Accessi concorrenti possono causare condizioni di race.

Meccanismi di sincronizzazione

Il kernel utilizza:

  • Spinlock
  • Mutex
  • Sezioni critiche
  • Disabilitazione temporanea degli interrupt

per garantire coerenza.

Affinità della CPU

La CPU affinity consente di associare preferenzialmente un processo a un core specifico per:

  • Migliorare la località della cache
  • Ridurre il costo di migrazione tra core

La migrazione tra core comporta invalidazioni di cache e costi aggiuntivi.

Comunicazione tra processi (IPC)

I processi cooperanti utilizzano meccanismi di IPC (InterProcess Communication).

Due modelli principali:

  • Memoria condivisa: comunicazione tramite una regione di memoria comune; è veloce ma richiede sincronizzazione.
  • Scambio di messaggi: basato su primitive send() e receive(), può essere sincrono (bloccante) o asincrono (non bloccante).

Esempi di sistemi IPC e comunicazione client-server

  • Pipe: canali di comunicazione, tipicamente tra processi correlati.
  • Socket: identificati da indirizzo IP e porta; fondamentali per la comunicazione in rete (TCP e UDP).
  • RPC (Remote Procedure Call): permettono di invocare procedure remote come se fossero locali.
  • Sistemi specifici: Mach utilizza porte e messaggi; Windows impiega le ALPC (Advanced Local Procedure Call) per la comunicazione locale.

Commenti