Esercizi su concorrenza e sincronizzazione
Esercizi sulla concorrenza
- Scrivere un programma che utilizzi due thread per contare da 0 a 100 in parallelo.
- Creare un programma che utilizzi più processi per calcolare la somma dei numeri da 1 a 1000000 utilizzando la concorrenza.
- Scrivere un programma che utilizzi thread per scaricare contemporaneamente più file da Internet.
- Creare un’applicazione che utilizzi la concorrenza per calcolare il fattoriale di un numero molto grande.
- Scrivere un programma che utilizzi processi per eseguire una ricerca parallela in una lista di nomi.
- Creare un’applicazione che utilizzi thread per gestire contemporaneamente più connessioni client in una chat room.
- Scrivere un programma che utilizzi la concorrenza per calcolare il prodotto scalare tra due vettori di grandi dimensioni.
- Creare un’applicazione che utilizzi processi per eseguire una ricerca parallela in una grande base di dati.
- Scrivere un programma che utilizzi thread per elaborare contemporaneamente più immagini in formato JPEG.
- Creare un’applicazione che utilizzi la concorrenza per calcolare il valore di una funzione matematica utilizzando diverse tecniche di ottimizzazione.
Per questi esercizi, è possibile utilizzare i seguenti moduli Python:
threading
: per creare e gestire threadmultiprocessing
: per creare e gestire processiqueue
: per condividere dati tra thread o processimutex
: per sincronizzare l’accesso a risorse condivisecondition
: per gestire condizioni di corsa tra thread o processisemaphore
: per limitare l’accesso a risorse condivise
Proposte per il laboratorio
- Creazione di un’applicazione per la gestione di una lista condivisa tra più processi, utilizzando tecnologie come
multiprocessing
oconcurrent.futures
. Gli studenti potrebbero lavorare insieme per creare le funzionalità di base come l’aggiunta e la rimozione di elementi dalla lista e sviluppare un sistema di sincronizzazione utilizzando lock o semafori. - Sviluppo di un’applicazione per la gestione di una chat room condivisa tra più processi, utilizzando tecnologie come
multiprocessing
oconcurrent.futures
. Gli studenti potrebbero lavorare insieme per creare le funzionalità di base come l’invio e la ricezione di messaggi e sviluppare un sistema di sincronizzazione utilizzando lock o semafori. - Creazione di un’applicazione per la gestione di una piattaforma di gioco online condivisa tra più processi, utilizzando tecnologie come
multiprocessing
oconcurrent.futures
. Gli studenti potrebbero lavorare insieme per creare le funzionalità di base come il movimento dei pezzi sulla scacchiera e sviluppare un sistema di sincronizzazione utilizzando lock o semafori. - Sviluppo di un’applicazione per la gestione di una piattaforma di collaborazione online condivisa tra più processi, utilizzando tecnologie come
multiprocessing
oconcurrent.futures
. Gli studenti potrebbero lavorare insieme per creare le funzionalità di base come la condivisione di documenti e sviluppare un sistema di sincronizzazione utilizzando lock o semafori. - Creazione di un’applicazione per la gestione di una piattaforma di streaming video condivisa tra più processi, utilizzando tecnologie come
multiprocessing
oconcurrent.futures
. Gli studenti potrebbero lavorare insieme per creare le funzionalità di base come la riproduzione di video e sviluppare un sistema di sincronizzazione utilizzando lock o semafori.
Soluzioni
Presentiamo la soluzione di alcuni dei progetti proposti.
1. lista condivisa
Ecco un esempio di implementazione di una lista condivisa tra più processi in Python utilizzando il modulo multiprocessing
:
In questo esempio, la classe SharedList
rappresenta una lista condivisa tra più processi. La lista è protetta da un lock per evitare conflitti di accesso tra i processi.
La funzione worker
rappresenta il compito che viene eseguito dai processi. Ogni processo aggiunge 10 elementi alla lista condivisa e stampa un messaggio per indicare l’aggiunta dell’elemento.
Infine, nel blocco if __name__ == "__main__":
, vengono creati due processi utilizzando la funzione multiprocessing.Process()
. I processi eseguono la funzione worker()
passandogli come argomenti la lista condivisa e il nome del processo. Alla fine dell’esecuzione dei processi, viene stampata la lista condivisa.
Nota: questo esempio è solo un esempio di base e potrebbe essere migliorato o adattato alle esigenze specifiche del progetto.
Esercizi sulle tecniche di sincronizzazione
La sincronizzazione è una parte importante della programmazione concorrente in Python. In questa sezione troverai 20 esercizi sulla sincronizzazione, divisi in tre livelli di difficoltà crescente.
Basics
- Conta fino a 10: Crea due thread che stampano i numeri da 1 a 10. Utilizza il modulo
threading
per creare e avviare i thread. - Somma di numeri: Crea due thread che sommano i numeri da 1 a 100. Utilizza il modulo
threading
per creare e avviare i thread, e utilizza una variabile condivisa per memorizzare il risultato finale. - Timer: Crea un thread che stampa l’ora corrente ogni secondo. Utilizza il modulo
threading
e la funzionetime.sleep()
per implementare il timer.
Locks
- Conteggio condiviso: Crea due thread che incrementano una variabile condivisa. Utilizza un lock per evitare race conditions.
- Accesso condiviso a una risorsa: Crea due thread che accedono a una risorsa condivisa (ad esempio, un file). Utilizza un lock per garantire l’accesso esclusivo alla risorsa.
- Protezione di una lista condivisa: Crea una lista condivisa e due thread che aggiungono elementi alla lista. Utilizza un lock per proteggere la lista dalle modifiche simultanee.
Condizioni e eventi
- Produttore/consumatore: Crea due thread, uno che produce numeri e l’altro che li consuma. Utilizza una coda condivisa e le condizioni per sincronizzare i thread.
- Barriera di sincronizzazione: Crea tre thread che stampano un messaggio in ordine sequenziale. Utilizza una barriera di sincronizzazione per garantire che i thread stampino il messaggio nella giusta sequenza.
- Eventi di terminazione: Crea due thread e utilizza gli eventi per gestire la loro terminazione. Il primo thread deve attendere che il secondo termini prima di terminare a sua volta.
Sincronizzazione avanzata
- Semafori: Crea tre thread che accedono a una risorsa condivisa. Utilizza i semafori per controllare l’accesso alla risorsa e prevenire race conditions.
- Lock con timeout: Modifica l’esercizio 4 del livello 2 in modo da utilizzare un lock con timeout per evitare deadlocks.
- Thread pool: Crea una pool di thread e utilizza le condizioni per gestire i task in ingresso e in uscita dalla pool.
Mix
- Produttore/consumatore con semafori: Modifica l’esercizio 1 del livello 4 in modo da utilizzare i semafori invece delle condizioni per sincronizzare i thread.
- Barriera di sincronizzazione con eventi: Modifica l’esercizio 3 del livello 3 in modo da utilizzare le barriere di sincronizzazione invece degli eventi per gestire la terminazione dei thread.
- Lock condiviso tra processi: Crea due processi che accedono a una risorsa condivisa. Utilizza un lock condiviso tra i processi per garantire l’accesso esclusivo alla risosa.
- Sincronizzazione con file di lock: Crea due thread che scrivono su un file condiviso. Utilizza un file di lock per sincronizzare l’accesso al file e prevenire race conditions.
- Sincronizzazione con pipe: Crea due processi che comunicano attraverso una pipe. Utilizza le pipe per sincronizzare i processi e scambiare dati tra di loro.