Lettori e scrittori, Barbiere sonnolento

Documenti analoghi
Problema dei Fumatori di sigarette. Problema dei Fumatori di sigarette. Problema dei Fumatori di sigarette

Architettura degli Elaboratori 2

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

Sushi bar problem. The Little Book of Semaphores by Allen B. Downey

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

ESERCIZIO SincrAmbGlob-1

Hilzer s Barbershop problem

Corso di Laboratorio di Sistemi Operativi

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

Esercitazione 15. Il problema dello Sleeping Barber

DTI / ISIN / Titolo principale della presentazione. La cena dei filosofi. Amos Brocco, Ricercatore, DTI / ISIN. 14 maggio 2012

Sistemi Operativi. Lezione 7 Comunicazione tra processi

Università degli Studi di Padova - Corso di Laurea in Informatica

Santa Claus Problem. The Little Book of Semaphores by Allen B. Downey

Sistemi Operativi Esercizi Sincronizzazione

Meccanismi di sincronizzazione. Scambio di messaggi

SOLUZIONE. ESERCIZIO PRODUTTORE CONSUMATORE (semafori)

Università degli Studi di Padova - Corso di Laurea in Informatica

Cenni ai Problemi classici di Sincronizzazione Processi Concorrenti. E. Mumolo

Sincronizzazione. Problemi di sincronizzazione tipici Stefano Quer Dipartimento di Automatica e Informatica Politecnico di Torino

Sistemi Operativi. Lezione 7-bis Esercizi

Architettura degli Elaboratori 2. Concetti preliminari (1) Concetti preliminari (2) Concetti preliminari (3) Grafo di allocazione delle risorse

Processi e Thread. Meccanismi di IPC (1)

Sistemi operativi. Lez. 6: primitive per la concorrenza e semafori

8 DEADLOCK. 8.1 Modello del Sistema. 8.1 Modello del Sistema

Esercizi Programmazione Concorrente

/////////////////////////////////// /// ESERCIZI SUI SEMAFORI /// /// Stefano Ferretti /// ///////////////////////////////////

CAPITOLO 23 PROBLEMA DEL BARBIERE

La mutua esclusione (dai sistemi concorrenti ai sistemi distribuiti) mutua esclusione

UNIVERSITÀ DEGLI STUDI DI BERGAMO

Problematiche dello scambio di messaggi Produttore-consumatore con scambio di messaggi

Realizzazione di Politiche di Gestione delle Risorse: i Semafori Privati

Sistemi Operativi Esercizi Ricapitolazione. Docente: Claudio E. Palazzi

Sincronizzazione Le sezioni scritiche

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

Programmazione multiprocesso

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

Corso sul linguaggio Java

Nota: lo studente si ricordi di inizializzare i valori delle variabili semaforo usate nella sua soluzione.

Corso sul linguaggio Java

SOLUZIONE. <l auto arriva all ingresso I> while PostiDisponibili == 0

Meccanismi di sincronizzazione: Semafori e Monitor

Sincronizzazione. Problemi di sincronizzazione tipici Stefano Quer Dipartimento di Automatica e Informatica Politecnico di Torino

Sistemi operativi. Lez. 6/7: primitive per la concorrenza e semafori

2. Teoria. [7 punti] La comunicazione tra processi nel sistema UNIX.

Sistemi operativi - Concetti ed esempi -Settima edizione

= PTHREAD_MUTEX_INITIALIZER

Prof. Pagani Corrado PROGRAMMAZIONE CONCORRENTE

Sincronizzazione di thread POSIX

Algoritmo di Dekker. Algoritmo di Peterson

Esercizio 1. Scrivere un programma C in cui: Il master thread:

Sistemi Operativi. Lez. 6: Problemi classici della programmazione concorrente

Semafori. Semafori classici con i thread POSIX 2

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

GESTIONE DEI PROCESSI E DEI THREADS IN UN SISTEMA LINUX (PARTE 3) 1

Nome Cognome N. di matricola (10 cifre) Riga Col

Introduzione all'algoritmica. 1 Primo esempio: il massimo di una sequenza.

Università degli Studi di Padova - Facoltà di Scienze MM.FF.NN. - Corso di Laurea in Informatica

Introduzione. Meccanismi di sincronizzazione: Semafori e Monitor. Semafori - Definizione. Semafori - Descrizione informale

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

Esercizi sui file. Esercizio 1. Soluzione. Domenico Cotroneo Dipartimento di Informatica e Sistemistica

[1.B] Si consideri un sistema con un solo processo attivo, il quale sta eseguendo la seguente porzione di codice:

Il costrutto monitor [Hoare 74]

Thread: sincronizzazione Esercitazioni del 09 Ottobre 2009

Sistemi Operativi e Laboratorio, Prova del 9/9/2016

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

18/12/2002 Descrivere il metodo di allocazione di file basato su indicizzazione a livelli multipli. Si consideri un file di dati F di 2048 record ed

Monitor. Introduzione. Struttura di un TDA Monitor

SEMAFORI. Semaforo. s--; Il valore di un semaforo s è legato al numero delle operazioni wait e signal eseguite su di esso dalla relazione:

Simulazione di semafori e rotonde: verifica dell'efficienza al variare del traffico

«Sciente e Tecnologie dei Beni Culturali»

LABORATORIO DI SISTEMI OPERATIVI

5f Esercizi Progr. Concorrente e Vari

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

Il monitor. Sistemi Operativi T AA

SISTEMI OPERATIVI L-A Prova scritta parziale finale del 18 Marzo 2003

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

Esercitazione [3] Sincronizzazione inter-processo

UNIVERSITÀ DEGLI STUDI DI BERGAMO

CAPITOLO 19 MUTUA ESCLUSIONE SUPPORTO SOFTWARE

Java threads (2) Programmazione Concorrente

Chiamata di procedura remota

Pr1: determinare il maggiore di n numeri interi n. Fondamenti di Informatica Prof. Vittoria de Nitto Personè

Chiamata di procedura remota

Array. // utente pippo $utente1 = array( username => pippo, password => pippo123, ruolo => amministratore );

Esercizio sui Semafori

Azioni atomiche. Definizioni. Proprietà

Esercitazioni 7 e 8. Bounded Buffer con sincronizzazione Java (1)

Introduzione al multithreading

Convenzioni per la chiamata a procedure

Esecuzione concorrente di transazioni

Sistemi Operativi. IPC: Inter-Process Communication

INFORMATICA AA Università degli Studi di Ferrara Facoltà di Scienze MM FF NN Corso di Laurea in «Scienze e Tecnologie per i Beni Culturali»

Informatica 3. LEZIONE 6: Il controllo dell esecuzione. Modulo 1: La gestione delle eccezioni Modulo 2: Programmazione concorrente

Programmazione multi threaded in Python. Linguaggi dinamici A.A. 2010/2011 1

Corso di Informatica

Decima Esercitazione. Accesso a risorse condivise tramite Monitor Java

Esercitazione [2] Concorrenza

Transcript:

DTI / ISIN / Titolo principale della presentazione 1 Lettori e scrittori, Barbiere sonnolento Amos Brocco, Ricercatore, DTI / ISIN 14 maggio 2012

Lettori e scrittori Problema che riproduce una situazione in cui ci sono più processi concorrenti che cercano di leggere e scrivere in una memoria (es. database) Più processi di lettura (lettori) possono tranquillamente accedere in maniera concorrente Se un processo di scrittura (scrittore) sta modificando i dati, nessun altro processo deve poter accedere, nemmeno i lettori (che potrebbero leggere dei dati inconsistenti)

Lettori e scrittori: soluzione favorevole ai lettori Più processi di lettura (lettori) possono tranquillamente accedere in maniera concorrente il primo lettore blocca l'accesso agli scrittori l'ultimo lettore sblocca l'accesso agli scrittori Se un processo di scrittura (scrittore) sta modificando i dati, nessun altro processo deve poter accedere, nemmeno i lettori (che potrebbero leggere dei dati inconsistenti)

Lettori e scrittori: soluzione favorevole ai lettori semaphore nlm = 1; /* Protegge numlet */ semaphore db = 1; /* Protegge dati */ int numlet = 0; thread lettore(void) numlet = numlet + 1; if (numlet == 1) down(&db); leggi(); numlet = numlet 1; if (numlet == 0) up(&db); processa_dati(); thread scrittore(void) genera_dati(); down(&db); scrivi(); up(&db);

Lettori e scrittori: soluzione favorevole ai lettori semaphore nlm = 1; semaphore db = 1; int numlet = 0; thread lettore(void) numlet = numlet + 1; if (numlet == 1) down(&db); leggi(); numlet = numlet 1; if (numlet == 0) up(&db); processa_dati(); Il primo lettore blocca i dati in modo da non lasciar entrare uno scrittore L'ultimo lettore sblocca i dati in modo da lasciar entrare uno scrittore (se era in attesa)

Lettori e scrittori: soluzione favorevole ai lettori Lo scrittore deve aspettare che tutti i lettori abbiano finito! Poi blocca l'accesso a altri thread (lettori / scrittori) thread scrittore(void) genera_dati(); down(&db); scrivi(); up(&db);

Favorire i lettori Se ci sono sempre lettori, lo scrittore potrebbe non aver mai l'occasione di scrivere: starvation! Per evitare questa situazione potremmo modificare il programma come segue: quando un lettore arriva e c'è uno scrittore in attesa, il lettore deve aspettare dietro lo scrittore invece di permettergli di entrare subito a leggere Concurrent Control with "Readers" and "Writers" P.J. Courtois,* F. H, 1971

Lettori e scrittori: costruzione di una soluzione favorevole agli scrittori Più processi di lettura (lettori) possono tranquillamente accedere in maniera concorrente Se un processo di scrittura (scrittore) sta modificando i dati, nessun altro processo deve poter accedere, nemmeno i lettori (che potrebbero leggere dei dati inconsistenti) il primo scrittore blocca l'accesso ai lettori l'ultimo scrittore sblocca l'accesso ai lettori

Lettori e scrittori: costruzione di una soluzione favorevole agli scrittori semaphore fs = 1; /* Flag scrittori: down quando entra primo scrittore */ semaphore nsm = 1; down(&nsm); numscr = numscr + 1; if (numscr == 1) down(&fs); up(&nsm); thread scrittore(void) genera_dati(); down(&db); scrivi(); up(&db); down(&nsm); numscr = numscr - 1; if (numscr == 0) up(&fs); up(&nsm); quando un lettore arriva e c'è uno scrittore in attesa, il lettore deve aspettare

Lettori e scrittori: costruzione di una soluzione favorevole agli scrittori semaphore nlm = 1; semaphore db = 1; int numlet = 0; thread lettore(void) numlet = numlet + 1; if (numlet == 1) down(&db); leggi(); numlet = numlet 1; if (numlet == 0) up(&db); processa_dati(); down(&fs); up(&fs); Nota: sblocco subito il semaforo fs per permettere la lettura concorrente di più lettori quando un lettore arriva e c'è uno scrittore in attesa, il lettore deve aspettare

Lettori e scrittori: costruzione di una soluzione favorevole agli scrittori semaphore nlm, nsm = 1; semaphore fs = 1; semaphore db = 1; int numlet = 0; int numscr = 0; thread lettore(void) down(&fs); numlet = numlet + 1; if (numlet == 1) down(&db); up(&fs); leggi(); numlet = numlet 1; if (numlet == 0) up(&db); processa_dati(); thread scrittore(void) genera_dati(); down(&nsm); numscr = numscr + 1; if (numscr == 1) down(&fs); up(&nsm); down(&db); scrivi(); up(&db); down(&nsm); numscr = numscr 1; if (numscr == 0) up(&fs); up(&nsm);... manca ancora qualcosa: se sia dei lettori che degli scrittori sono in attesa su down(&fs), non viene data la precedenza agli scrittori!

Lettori e scrittori: soluzione favorevole agli scrittori semaphore mutex, nlm, msm = 1; semaphore fs = 1; /* Flag scrittori */ semaphore db = 1; int numlet = 0; int numscr = 0; thread lettore(void) down(&mutex); down(&fs); numlet = numlet + 1; if (numlet == 1) down(&db); up(&fs); up(&mutex); leggi(); numlet = numlet 1; if (numlet == 0) up(&db); processa_dati(); thread scrittore(void) genera_dati(); down(&nsm); numscr = numscr + 1; if (numscr == 1) down(&fs); up(&nsm); down(&db); scrivi(); up(&db); down(&nsm); numscr = numscr 1; if (numscr == 0) up(&fs); up(&nsm); Con mutex non posso avere più lettori in attesa su down(&fs), quindi quando faccio up(&fs) se sblocco qualcuno in attesa può trattarsi solo di uno scrittore

Lettori e scrittori: soluzione favorevole agli scrittori semaphore mutex, nlm, msm = 1; semaphore fs = 1; /* Flag scrittori */ semaphore db = 1; int numlet = 0; int numscr = 0; thread lettore(void) down(&mutex); down(&fs); numlet = numlet + 1; if (numlet == 1) down(&db); up(&fs); up(&mutex); leggi(); Vogliamo garantire che ci sia al massimo un lettore in attesa su '&l' Se non ci sono scrittori qui non devo aspettare, altrimenti loro hanno la precedenza Mi metto in coda, se sono il primo impedisco agli scrittori di continuare Lascio passare il prossimo numlet = numlet 1; if (numlet == 0) up(&db); processa_dati(); Se sono l'ultimo lettore, gli scrittori possono passare

Lettori e scrittori: soluzione favorevole agli scrittori Mi metto in coda, se sono il primo impedisco ai lettori di mettersi in coda (aspetteranno prima) Aspetto la possibilità di scrivere (i.e. che esca il lettore corrente), poi posso scrivere thread scrittore(void) genera_dati(); down(&nsm); numscr = numscr + 1; if (numscr == 1) down(&fs); up(&nsm); down(&db); scrivi(); up(&db); Ho finito, sveglio un lettore che era in attesa down(&nsm); numscr = numscr 1; if (numscr == 0) up(&fs); up(&nsm);

Favorire gli scrittori Se ci sono sempre scrittori, un lettore potrebbe non aver mai l'occasione di leggere: starvation!

Lettori e scrittori: soluzione equa Più processi di lettura (lettori) possono tranquillamente accedere in maniera concorrente il primo lettore blocca l'accesso agli scrittori l'ultimo lettore sblocca l'accesso agli scrittori Se un processo di scrittura (scrittore) sta modificando i dati, nessun altro processo deve poter accedere, nemmeno i lettori (che potrebbero leggere dei dati inconsistenti) Viene stabilito l'ordine di arrivo se arriva uno scrittore, aspetta finché tutti i lettori correntemente in esecuzione (non in attesa!) finiscono, e poi ha la precedenza

Soluzione equa semaphore nlm, msm = 1; semaphore ordine = 1; semaphore db = 1; int numlet = 0; thread lettore(void) down(&ordine); numlet = numlet + 1; if (numlet == 1) down(&db); up(&ordine); thread scrittore(void) genera_dati(); down(&ordine); down(&db); up(&ordine); scrivi(); up(&db); leggi(); numlet = numlet 1; if (numlet == 0) up(&db); processa_dati(); Presupponiamo che i thread in attesa sul semaforo ordine vengano risvegliati nell'ordine corretto

Soluzione equa semaphore nlm, msm = 1; semaphore ordine = 1; semaphore db = 1; int numlet = 0; thread lettore(void) down(&ordine); numlet = numlet + 1; if (numlet == 1) down(&db); up(&ordine); Mi metto in coda Sono fuori dalla coda, pronto per leggere leggi(); numlet = numlet 1; if (numlet == 0) up(&db); processa_dati(); Il semaforo 'db' blocca gli scrittori fintanto che ci sono lettori in esecuzione...

Soluzione equa Mi metto in coda Fuori dalla coda thread scrittore(void) genera_dati(); down(&ordine); down(&db); up(&ordine); scrivi(); up(&db); Appena uno scrittore viene risvegliato si mette in attesa su db... finché non ottiene l'accesso ogni altro thread dovrà aspettare su 'ordine': i lettori quindi non potranno più aumentare

Il problema del barbiere sonnolento (Sleeping Barber, E.Dijkstra 1965) da Modern Operating Systems, 2nd Ed., A. Tanenbaum

Il problema del barbiere sonnolento (Sleeping Barber, E.Dijkstra 1965) Il barbiere ha una sedia per tagliare i capelli e per dormire e una sala d aspetto con N sedie per i clienti. Il barbiere, quando ha terminato un servizio, guarda nella sala d aspetto se ci sono altri clienti. Se sì, fa accomodare il prossimo sulla sua sedia, altrimenti si mette lui a dormire. Il cliente, quando arriva, guarda cosa sta facendo il barbiere. Se dorme, lo sveglia. Se sta già lavorando, va nella sala d aspetto e, se la sala non è piena, attende il suo turno, altrimenti se ne va.

Il barbiere sonnolento: soluzione ingenua thread barbiere if (clienti > 0) stato=lavora /* Fai accomodare cliente */ up(semaforo_clienti) clienti=clienti 1 esegue servizio else stato=dorme down(semaforo_barbiere) semaforo_clienti = 0 semaforo_barbiere = 0 stato = dorme thread cliente if (stato==dorme)/* Sveglia! */ up(semaforo_barbiere) if (clienti < N) /* Si mette in coda */ clienti = clienti+1 down(semaforo_clienti) riceve servizio else se ne va

Il barbiere sonnolento: soluzione ingenua Attenzione ai deadlock! Il barbiere guarda nella sala d aspetto. Non c è nessuno (clienti=0), va sulla sua sedia e dorme (stato=dorme). Dopo aver visto clienti=0 e prima di porre stato=dorme, arriva un cliente che vede il barbiere ancora stato=lavora. Va nella sala sala d aspetto e attende l'incremento del semaforo_clienti, che non avverrà, a meno che non arrivi un altro cliente.

Il barbiere sonnolento: soluzione corretta thread barbiere blocca mutex if (clienti > 0) stato=lavora up(semaforo_clienti) clienti=clienti 1 sblocca mutex esegue servizio else stato=dorme sblocca mutex down(semaforo_barbiere) semaforo_clienti = 0 semaforo_barbiere = 0 stato = dorme thread cliente blocca mutex if (stato==dorme) up(semaforo_barbiere) if (clienti < N) clienti = clienti+1 sblocca mutex down(semaforo_clienti) riceve servizio else sblocca mutex se ne va