Title: Concorrenza e Sincronizzazione di Thread e Processi
1Concorrenza e Sincronizzazione di Thread e
Processi
2Concorrenza e Sincronizzazione
- Obiettivi
- garantire la mutua esclusione nellaccesso a
risorse condivise da parte di thread/processi
concorrenti - Più in generale, stabilire un coordinamento fra
(sincronizzare) le azioni di thread/processi
concorrenti
3Mutua-esclusione
- Problemi da risolvere
- Aggiornamenti perduti (lost update)
- Azione aggiornamento concorrente di un dato da
parte di più thread/processi - Risultato lultimo valore sovrascrive tutti gli
altri - Letture inconsistenti (inconsistent read)
- Azione lettura di un dati che successivamente
vengono modificati da altri thread/processi
concorrenti - Risultato i calcoli basati sui dati non
aggiornati producono risultati sbagliati - Vincoli
- Garantire il massimo di attività concorrenti
(liveness) - Evitare lo stallo (deadlock)
- NB Se laccesso alle variabili condivise avviene
solo in lettura (nessun thread cambia I valori)
non ci sono mai problemi di mutua-esclusione
4Esempio di inconsistenza
- a 1 1 è sempre uguale a zero?
- Un caso pratico. Si supponga che
- a sia una variabile condivisa da 200 thread
- 100 thread incrementano a
- 100 thread decrementano a
- qual è il valore finale di a?
5Un occhio al codice assembler
- Decremento di a
- load R1, a
- sub R1, 1
- Store a,R1
- Incremento di a
- load R1, a
- add R1, 1
- store a, R1
6Possibile sequenza di esecuzione
- a vale inizialmente 0, comincia Thread 1
- load R1, a // legge il valore di a, R1 0
- add R1, 1 // incremento, R1 1
- Preemption, cambio contesto, comincia Thread 2
- load R1, a // legge il valore di a, R1 0
- sub R1, 1 // decremento, R1 -1
- store a, R1 // scrive valore di a, a -1
- Preemption, cambio contesto, continua Thread 1
- (NB Loperazione 5 ha reso inconsistente la
lettura 1) - store a, R1 // scrive il valore di a, a 1
- Fine, a vale 1 invece che 0
- (NB Loperazione 6 ha sovrascritto
laggiornamento 5)
Inconsistent read
Lost update
7Soluzione sezioni critiche
- Una sezione critica viene eseguita senza cambi di
contesto intermedi -
- Decremento di a
- test_and_set lock
- load R1, a
- sub R1, 1
- store a,R1
- unset lock
- Incremento di a
- test_and_set lock
- load R1, a
- add R1, 1
- store a, R1
- unset lock
8Mutua Esclusione in Windows Oggetti Mutex
- Mutex Mutual Exclusion object
- CreateMutex()
- ReleaseMutex()
- WaitForSingleObject()
- A basso livello, Windows usa un meccanismo
hardware di sincronizzazione (sul modello
test-and-set) per implementare un lock
primitivo chiamato spinlock
9Procedimento
- Si crea loggetto mutex
- uso CreateMutex()
- Si inizia la sezione critica, occupando loggetto
mutex - uso WaitForSingleObject()
- Alla fine della regione critica, si rilascia
loggetto mutex - uso ReleaseMutex()
10CreateMutex
- Funzione creazione di un nuovo oggetto Mutex
- HANDLE CreateMutex(LPSECURITY_ATTRIBUTES
lpMutexAttributes, BOOL bInitialOwner, LPCTSTR
lpName) - lpMutexAttributes attributi di sicurezza
- bInitialOwner se true, il Mutex viene risulta
già occupato dal processo/thread che lo crea - lpName nome simbolico delloggetto
- Restituisce lo handle del Mutex creato
11WaitForSingleObject
- Funzione test_and_set di un oggetto Mutex
- DWORD WaitForSingleObject(HANDLE hMutex, DWORD
dwMilliseconds) - hMutex il mutex da occupare
- dwMilliseconds timeout di attesa (eventualmente
INFINITE) - Restituisce lindicazione del motivo della
terminazione (es. Timeout)
12ReleaseMutex
- Funzione rilascio (unlock) di un Mutex
precedentemente occupato - BOOL ReleaseMutex(HANDLE hMutex)
- hMutex il mutex da rilasciare
- Restituisce TRUE in caso di successo
13Stati degli Handle e WaitForSingleObject
- Gli handle sono associati a eventi di
sincronizzazione, in base ai quali possono
transire fra due possibili stati - Signaled
- unsignaled
evento di sincronizzazione
WaitForSingleObject bloccata
Handle signaled
Handle unsignaled
WaitForSingleObject eseguita
14Handle e WaitForSingleObjectCaso dei Mutex
CreateMutex(,FALSE,)
evento di sincronizzazioneReleaseMutex()
WaitForSingleObject bloccata
Handle Mutex signaled
Handle Mutex unsignaled
WaitForSingleObject eseguita
15Handle e WaitForSingleObjectCaso di
Thread/Processi
CreateProcess() CreateThread()
evento di sincronizzazioneterminazione del
thread/processo
WaitForSingleObject bloccata
Handle thread signaled
Handle thread unsignaled
WaitForSingleObject eseguita
16Il nome degli oggetti
- Perché è possibile dare un nome ad un oggetto
come un Mutex? - Dare un nome ad un oggetto significa dare
visibilità globale alloggetto - Gli oggetti visibili globalmente sono accessibili
da altri processi - Procedimento generale
- Se in fase di creazione di un oggetto si
specifica il nome di un oggetto che esiste già
nel sistema, viene restituito lo Handle
delloggetto esistente
17Handle table dei processi e object manager
globale
Gestore unico degli oggetti li crea, cancella,
li contiene, ecc.
- Object Manager
- Oggetto 1
- Oggetto 2
- Oggetto 3
- Oggetto 4
18Condivisione dei Mutex
- Se in CreateMutex di specifica il nome (terzo
par.) di un Mutex già esistente - Viene restituito lo handle al Mutex esistente
- Il secondo parametro (occupazione iniziale del
Mutex) viene ignorato
19Coordinamento con Eventi
- Un evento è una segnalazione di un
processo/thread (solitamente relativa a un
cambiamento di stato) che può essere ricevuta da
un altro processo/thread - Il processo/thread che gestisce levento (e lo
segnala) viene detto observer - Il processo che riceve levento (e reagisce di
conseguenza) viene detto listener - CreateEvent()
- per creare un nuovo evento o connettersi ad un
evento esistente - SetEvent()
- per segnalare un evento
- WaitForSingleObject()
- per ascoltare un evento, bloccandosi in attesa
che sia segnalato
20Handle e WaitForSingleObjectCaso degli Eventi
CreateEvent()
evento di sincronizzazioneSetEvent(...)
WaitForSingleObject bloccata
Handle evento signaled
Handle evento unsignaled
WaitForSingleObject eseguita
21CreateEvent
- Funzione creazione di un nuovo oggetto evento o
connessione ad uno esistente - HANDLE CreateEvent(
- LPSECURITY_ATTRIBUTES lpEventAttributes,
- BOOL bManualReset
- BOOL bInitialState
- LPCTSTR lpName)
-
- lpEventAttributes attributi di sicurezza
- bManualReset gestione manuale del reset (vedere
ResetEvent) - bInitialOwner se true, levento risulta già
segnalato alla creazione - lpName nome simbolico delloggetto
- Restituisce lo handle dellevento creato (o
connesso)
22SetEvent
- Funzione segnalazione di un evento
- BOOL SetEvent(HANDLE hEvent)
- hEvent levento da segnalare
- Restituisce TRUE in caso di successo