LABORATORIO DI SISTEMI OPERATIVI

Documenti analoghi
Libreria Linux Threads. Threads nel S.O. Linux. Primitive per la gestione dei thread. Portabilità: libreria pthreads (Posix).

LinuxThreads. LinuxThreads: monitor & variabili condizione

= PTHREAD_MUTEX_INITIALIZER

Università di Roma Tor Vergata Corso di Laurea triennale in Informatica Sistemi operativi e reti A.A Pietro Frasca.

LABORATORIO DI SISTEMI OPERATIVI

Università di Roma Tor Vergata Corso di Laurea triennale in Informatica Sistemi operativi e reti A.A Pietro Frasca.

Sincronizzazione di thread POSIX

Sistemi operativi. Corso di Laurea Triennale in Ingegneria Informatica. Lezione 7 Mutex Condition Esempi di utilizzo

Esercizio sul Monitor. Ponte con utenti grassi e magri 11 Novembre 2013

Corso di Laboratorio di Sistemi Operativi

Nona Esercitazione. Thread e memoria condivisa Sincronizzazione tramite semafori

Corso di Laboratorio di Sistemi Operativi A.A

Monitor [Hoare 74] Costrutto sintattico che associa un insieme di procedure/funzioni (entry) ad una struttura dati comune a più processi.

Monitor [Hoare 74] Uso del monitor

Monitor. Le procedure entry sono le sole operazioni che possono essere utilizzate dai processi per accedere alle variabili comuni.

Cosa sono i semafori?

Creazione di thread. In Linux si utilizzano le librerie pthread (POSIX thread) per lavorare con i thread:

Esercizi di utilizzo del semaforo semplice di competizione per l'uso di una risorsa comune

Thread thread lightweight process

Lab 4: Locks, Condition Variables in Java

Nona Esercitazione. Thread e memoria condivisa Sincronizzazione tramite semafori

I thread nel sistema operativo LINUX: Linuxthreads

Sincronizzazione di thread POSIX

Perche le CPU multicore

Corso di Informatica

Laboratorio su Programmazione Concorrente in C. Problemi classici e derivati Dalla Ottava lezione di laboratorio in avanti

Le risorse. Alcune definizioni

Sistemi Operativi (M. Cesati)

Esercitazione 2! Mutex e semafori POSIX. 3 Novembre 2016

Laboratorio su Programmazione Concorrente in C. Problemi classici e derivati Dalla Ottava lezione di laboratorio in avanti

Università di Roma Tor Vergata Corso di Laurea triennale in Informatica Sistemi operativi e reti A.A Pietro Frasca.

Esercitazione 2 Sincronizzazione con semafori. 31 Ottobre 2013

SEMAFORI SEMAFORI. Sul semaforo sono ammesse solo due operazioni (primitive)

Il costrutto monitor [Hoare 74]

Cosa sono i semafori?

Soluzioni ai problemi di Mutua Esclusione Primitive di sincronizzazione. Soluzioni ai problemi di Mutua EsclusionePrimitive di sincronizzazione

Sistemi Operativi e Laboratorio, Prova del 5/4/2016

Sistemi Operativi (M. Cesati)

Università di Roma Tor Vergata Corso di Laurea triennale in Informatica Sistemi operativi e reti A.A Pietro Frasca.

Esercitazione E9 Sincronizzazione

Chiamata di procedura remota

Esercitazione [4] Produttore/Consumatore

Chiamata di procedura remota

Java Virtual Machine. Indipendenza di java dalla macchina ospite. I threads in Java

LinuxThreads: I thread nel sistema operativo LINUX: Linuxthreads

Università di Roma Tor Vergata Corso di Laurea triennale in Informatica Sistemi operativi e reti A.A Pietro Frasca.

Università di Roma Tor Vergata Corso di Laurea triennale in Informatica Sistemi operativi e reti A.A Pietro Frasca.

Il monitor. Sistemi Operativi T AA

LinuxThreads: I thread nel sistema operativo LINUX: Linuxthreads. LinuxThreads. LinuxThreads

Esercizio monitor con pthreads

Architetture dei Calcolatori e Sistemi Operativi

Esercitazione n.2! 30 Ottobre Obiettivi: Programmazione pthreads: Sincronizzazione thread posix: mutua esclusione: pthread_mutex semafori

Thread: sincronizzazione Esercitazioni del 16 Ottobre 2009

Esercitazione [9] Riepilogo sui Semafori

Università di Roma Tor Vergata Corso di Laurea triennale in Informatica Sistemi operativi e reti A.A Pietro Frasca.

Università degli Studi della Calabria Corso di Laurea in Ingegneria Informatica A.A. 2001/2002. Sistemi Operativi Corsi A e B. Esercitazioni 3 e 4

Esercitazioni 3 e 4. Sincronizzazione dei Processi (2 a parte)

Lab 2: Semafori, Barriere, Variabili atomiche in Java

Università di Roma Tor Vergata Corso di Laurea triennale in Informatica Sistemi operativi e reti A.A Pietro Frasca.

Sistemi Operativi (M. Cesati)

Sistemi Operativi (M. Cesati)

CAPITOLO 22 PROBLEMA DEL PRODUTTORE/CONSUMATORE

Università di Roma Tor Vergata Corso di Laurea triennale in Informatica Sistemi operativi e reti A.A Pietro Frasca.

Esercitazione [11] Riepilogo sui Semafori. Sistemi di Calcolo - Secondo modulo (SC2) Programmazione dei Sistemi di Calcolo Multi-Nodo

Lab 2: Sincronizzazione diretta/indiretta in Java

Sistemi Operativi (M. Cesati)

CAPITOLO 17 PROBLEMI DEL PRODUTTORE/CONSUMATORE v1

LinuxThreads: I thread nel sistema operativo LINUX: Linuxthreads

Università di Roma Tor Vergata Corso di Laurea triennale in Informatica Sistemi operativi e reti A.A Pietro Frasca.

Sistemi operativi. Lez. 9: primitive per la concorrenza i semafori

Sistemi Operativi (M. Cesati)

Architettura degli Elaboratori 2

Esercitazioni 13 e 14

Esercizio Sincronizzazione Thread

ESERCIZIO SincrAmbGlob-1

I Thread in Java parte 2: Sincronizzazione. Sistemi Operativi T AA

Processi e Thread. Meccanismi di IPC (1)

Il costrutto monitor

Sistemi operativi - Concetti ed esempi -Settima edizione

Mutua esclusione. Una variabile condizione non fornisce la mutua esclusione. C'è bisogno di un mutex per poter sincronizzare l'accesso ai dati.

Esempio: la Toilette Unisex

Problema del buffer limitato. Lorenzo Gallucci

Problema dei Produttori e dei Consumatori

Unix/Linux Threads. la memoria globale (l accesso richiede sincronizzazione); i signal handlers e le disposizioni per i segnali;

I Thread in Java! parte 2:! Sincronizzazione!

Sincronizzazione Le sezioni scritiche

Sistemi Operativi. Lezione 7-bis Esercizi

Decima Esercitazione. Accesso a risorse condivise tramite Monitor Java

LinuxThreads. I thread nel sistema operativo LINUX: Linuxthreads. LinuxThreads: Caratteristiche. Rappresentazione dei threads

Sincronizzazione dei processi. Capitolo 5 -- Silberschatz

Esercitazione [2] Concorrenza

Il monitor. Sistemi Operativi T AA

Comunicazione con sincronizzazione estesa

Università di Roma Tor Vergata Corso di Laurea triennale in Informatica Sistemi operativi e reti A.A Pietro Frasca.

Esercitazione [3] Sincronizzazione inter-processo

Sistemi Operativi. IPC: Inter-Process Communication

Sistemi Operativi e Laboratorio, Prova del 6/4/2017 versione A

Transcript:

LABORATORIO DI SISTEMI OPERATIVI Corso di Laurea Triennale in Ingegneria Informatica A.A. 2018/2019 Guglielmo Cola Email: g.cola@iet.unipi.it Web: iet.unipi.it/g.cola

Thread POSIX nel sistema Linux (parte II) Sincronizzazione dei thread Variabili condizione (condition) Esercizi Esercitazione 9

Sincronizzazione dei thread Il mutex è lo strumento messo a disposizione dalla libreria pthread per la sincronizzazione indiretta dei thread o Permette di garantire l'accesso in mutua esclusione a una risorsa condivisa Per la sincronizzazione diretta dei thread la libreria definisce le variabili condizione (condition variables) o Un thread può sospendersi in attesa del verificarsi di una determinata condizione o Permette di realizzare politiche più avanzate di accesso alle risorse condivise e di sincronizzare i thread

Variabili condizione Una variabile condizione è di fatto una coda nella quale i thread possono sospendersi volontariamente in attesa di una condizione Definizione: pthread_cond_t C Funzione di inizializzazione: int pthread_cond_init(pthread_cond_t* C, pthread_cond_attr_t* attr) o pthread_cond_t* C Puntatore alla variabile condizione da inizializzare o pthread_cond_attr_t* attr Attributi specificati per la condizione, inizializzata a default se attr=null.

Variabili condizione Un thread può effettuare due "operazioni" su una variabile condition o Sospendersi (wait) sulla variabile condition. Il thread, dopo aver verificato una determinata condizione logica, si sospende sulla variabile condition, in attesa di essere "risvegliato" da un altro thread o Risvegliare uno dei thread (signal) o tutti i thread (broadcast) sospesi sulla variabile condition

Wait La sospensione (wait) viene utilizzata al verificarsi di una particolare condizione logica o Esempio: un thread produttore ha verificato che il buffer condiviso è pieno, quindi si blocca sulla condition "pieno" in attesa che un thread consumatore lo risvegli (dopo aver liberato il buffer) Schema generico di utilizzo della wait: while (condizione logica) wait(condition_variable); Perché while e non if? o Quando il thread viene risvegliato non va subito in esecuzione (la signal della libreria pthread è di tipo signal & continue): altri thread potrebbero inserirsi e alterare la condizione (nell'esempio del produttore/consumatore, un altro thread produttore potrebbe riempire nuovamente il buffer) o E' quindi necessario ricontrollare la condizione dopo essere stati svegliati

Wait e mutua esclusione La "condizione logica" (es. elementi_nel_buffer == MAX) è basata su una risorsa condivisa (es. elementi_nel_buffer) o La verifica della condizione deve essere eseguita in mutua esclusione Tenendo conto di questo aspetto, la primitiva di wait offerta dalla libreria pthread permette di "associare" una variabile mutex a una variabile condition. In questo modo: o L'accesso in mutua esclusione sulla condizione logica viene rilasciato quando il thread si sospende con la wait o Il thread, dopo essere stato risvegliato, prova automaticamente ad eseguire di nuovo il lock sulla variabile mutex (se il mutex è occupato, il thread si blocca in attesa che venga liberato prima di proseguire)

Primitiva wait int pthread_cond_wait(pthread_cond_t* C, pthread_mutex_t* M) o pthread_cond_t* C Variabile condizione su cui sospendersi o pthread_mutex_t* M Mutex associato alla variabile condizione: viene liberato automaticamente quando il thread si sospende; viene eseguito un nuovo lock quando il thread viene risvegliato. La chiamata ha due effetti: o Il thread viene sospeso nella coda associata a C o Il mutex M viene liberato (quando il thread verrà risvegliato, proverà nuovamente a fare lock su M)

Risveglio primitiva signal Il risveglio di un thread sospeso su una variabile condition C avviene mediante la primitiva signal: int pthread_cond_signal(pthread_cond_t* C) Come conseguenza della signal: o Se esistono thread in coda sulla condition, uno viene risvegliato o Se non vi sono thread sospesi, non ha alcun effetto La politica della signal della libreria pthread è di tipo signal & continue o Il thread che esegue la signal continua la sua esecuzione e mantiene il controllo del mutex fino al suo esplicito rilascio o Il thread che aveva effettuato la wait ed è stato risvegliato deve verificare nuovamente la condizione

Risveglio primitiva broadcast Per risvegliare tutti i thread in coda su una condition, è possibile utilizzare la funzione: int pthread_cond_broadcast(pthread_cond_t* C)

Esempio 1 produttore e consumatore Due thread accedono a una risorsa condivisa, ad esempio un buffer di interi gestito in modo circolare (ring buffer) o Il thread consumatore preleva valori (legge) dal buffer o Il thread produttore inserisce nuovi valori (scrive) nel buffer La gestione del buffer ha due vincoli: Non si può prelevare dal buffer vuoto Non si può inserire nel buffer pieno

Esempio 1 produttore e consumatore Si può realizzare la risorsa condivisa in questo modo: typedef struct { int buffer[buffer_size]; int readind, writeind; int cont; // indici di read/write nel buffer // elementi nel buffer pthread_mutex_t M; // per garantire accesso esclusivo alle risorse pthread_cond_t FULL; pthread_cond_t EMPTY; // condition var. buffer pieno // condition var. buffer vuoto } risorsa;

Esempio 1 produttore e consumatore La risorsa deve essere opportunamente inizializzata: risorsa r; // variabile globale, condivisa da tutti i thread int main() { pthread_mutex_init(&r.m, NULL); pthread_cond_init(&r.full, NULL); pthread_cond_init(&r.empty, NULL); } r.readind = r.writeind = r.cont = 0;

Esempio 1 consumatore Il consumatore deve o Assicurarsi che il buffer non sia vuoto prima di prelevare un dato o Risvegliare un produttore (se c'è) dopo aver prelevato un dato int val; // per il dato che verrà prelevato dal buffer pthread_mutex_lock(&r.m); while (r.cont == 0) // buffer vuoto? pthread_cond_wait(&r.empty, &r.m); // buffer vuoto, attendi // Preleva un dato e aggiorna lo stato del ring buffer. val = r.buffer[r.readind]; r.cont--; r.readind = (r.readind+1)% BUFFER_SIZE; // gestione circolare // Risveglia un eventuale thread produttore pthread_cond_signal(&r.full); pthread_mutex_unlock(&r.m);

Esempio 1 produttore Il produttore deve o Assicurarsi che il buffer non sia pieno prima di inserire un dato o Risvegliare un consumatore eventualmente sospeso pthread_mutex_lock(&r.m); while (r.cont == BUFFER_SIZE) // buffer pieno? pthread_cond_wait(&r.full, &r.m); // buffer pieno, attendi // Inserisci un dato aggiorna lo stato del ring buffer. r.buffer[r.writeind] = val; r.cont++; r.writeind = (r.writeind+1) % BUFFER_SIZE; // gestione circolare // Risveglia un eventuale thread consumatore pthread_cond_signal(r.empty); pthread_mutex_unlock(&r.m);

Esempio 2 accesso limitato a risorsa L'utilizzo delle variabili condition permette di realizzare politiche di accesso a una risorsa più avanzate Ad esempio, si immagini uno scenario in cui o NTHREADS utilizzano (periodicamente) una risorsa o La risorsa può essere utilizzata contemporaneamente da un numero massimo MAX_T di thread o NTHREADS > MAX_T

Esempio 2 accesso limitato a risorsa In questo caso si può utilizzare una variabile condition PIENO associata alla condizione: #thread che usano la risorsa == MAX_T Un thread esegue una "fase di ingresso" prima di usare la risorsa e una "fase di uscita" dopo aver usato la risorsa

Esempio 2 accesso limitato a risorsa Variabili globali #DEFINE MAX_T 10 int n_users = 0; // numero di thread che stanno usando la risorsa pthread_cond_t FULL; // condition var. limite di utilizzo raggiunto pthread_mutex_t M; // Mutex per l'accesso esclusivo a n_users

Esempio 2 accesso limitato a risorsa Fase di ingresso o Il thread controlla se è stato raggiunto il numero massimo di utilizzatori, ed eventualmente si sospende pthread_mutex_lock(&m); while (n_users == MAX_T) // massimo numero di users raggiunto pthread_cond_wait(&full, &M); // attendi n_users++; pthread_mutex_unlock(&m); // rilascio il lock // Uso della risorsa

Esempio 2 accesso limitato a risorsa Fase di uscita o Il thread, dopo aver usato la risorsa, aggiorna lo stato della risorsa e risveglia un thread eventualmente sospeso // Uso della risorsa pthread_mutex_lock(&m); n_users--; pthread_cond_signal(&full); pthread_mutex_unlock(&m);

Esercizio 1 Completare il codice in es1.c in modo che le funzioni deposit e withdraw operino correttamente sul saldo (balance) di un conto corrente

Esercizio 2 Completare il file es2.c in modo da ottenere questa sincronizzazione fra i thread: o I thread, prima di terminare, "aspettano" che anche gli altri abbiano terminato la sleep Utilizzare un intero condiviso "checked_threads" che per contare i thread che hanno terminato la sleep Utilizzare una variabile condition per sospendere i thread in attesa degli altri L'ultimo thread a raggiungere il "checkpoint" dopo la sleep provvede a svegliare gli altri, in modo che tutti possano terminare.

Esercizio 3 Il codice in es3.c simula il comportamento di alcuni giocatori che provano a indovinare un numero sorteggiato dal main o Il main sceglie un numero o I thread figli provano a indovinare o Se nessuno ha indovinato, il main fornisce un suggerimento (intervallo) e la scommessa viene ripetuta Completare il codice dei thread "giocatori" in modo da garantire la corretta sincronizzazione fra thread "giocatori" e thread main o Il thread giocatore deve inserire la sua "scommessa" nel buffer e risvegliare il thread main se tutti i giocatori hanno già fatto la loro scommessa o Il thread giocatore deve attendere che i risultati siano pronti prima di poter giocare di nuovo (se è necessario un altro turno per stabilire il vincitore)