Definizione: concorrenza
La concorrenza è la proprietà di un sistema operativo di far progredire nello stesso intervallo di tempo le stesse unità d’elaborazione, 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.
Per stimare quanto si guadagna dall’implementazione del parallelismo in un programma, si usa la legge di Amdahl.
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.