Concorrenza e Sincronizzazione di Thread e Processi.

22
Concorrenza e Sincronizzazione di Thread e Processi

Transcript of Concorrenza e Sincronizzazione di Thread e Processi.

Page 1: Concorrenza e Sincronizzazione di Thread e Processi.

Concorrenza e Sincronizzazione di Thread e Processi

Page 2: Concorrenza e Sincronizzazione di Thread e Processi.

Concorrenza e Sincronizzazione

• Obiettivi– garantire la mutua esclusione nell’accesso a

risorse condivise da parte di thread/processi concorrenti

– Più in generale, stabilire un coordinamento fra (sincronizzare) le azioni di thread/processi concorrenti

Page 3: Concorrenza e Sincronizzazione di Thread e Processi.

Mutua-esclusione• Problemi da risolvere

– Aggiornamenti perduti (lost update)• Azione: aggiornamento concorrente di un dato da parte di più

thread/processi• Risultato: l’ultimo 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 l’accesso alle variabili condivise avviene solo in lettura (nessun thread cambia I valori) non ci sono mai problemi di mutua-esclusione

Page 4: Concorrenza e Sincronizzazione di Thread e Processi.

Esempio 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?

Page 5: Concorrenza e Sincronizzazione di Thread e Processi.

Un 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

100 thread per ogni sequenza

Page 6: Concorrenza e Sincronizzazione di Thread e Processi.

Possibile sequenza di esecuzionea vale inizialmente 0, comincia Thread 1

1. load $R1, a // legge il valore di a, $R1 = 02. add $R1, 1 // incremento, $R1 = 1

Preemption, cambio contesto, comincia Thread 2

3. load $R1, a // legge il valore di a, $R1 = 04. sub $R1, 1 // decremento, $R1 = -15. store a, $R1 // scrive valore di a, a = -1

Preemption, cambio contesto, continua Thread 1(NB: L’operazione 5 ha reso inconsistente la lettura 1)

6. store a, $R1 // scrive il valore di a, a = 1

Fine, a vale 1 invece che 0(NB: L’operazione 6 ha sovrascritto l’aggiornamento 5)

Inconsistentread

Lost update

Page 7: Concorrenza e Sincronizzazione di Thread e Processi.

Soluzione: 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

Page 8: Concorrenza e Sincronizzazione di Thread e Processi.

Mutua 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

Page 9: Concorrenza e Sincronizzazione di Thread e Processi.

Procedimento

• Si crea l’oggetto mutex– uso CreateMutex()

• Si inizia la sezione critica, occupando l’oggetto mutex– uso WaitForSingleObject()

• Alla fine della regione critica, si rilascia l’oggetto mutex– uso ReleaseMutex()

Page 10: Concorrenza e Sincronizzazione di Thread e Processi.

CreateMutex

• 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 dell’oggetto

• Restituisce lo handle del Mutex creato

Page 11: Concorrenza e Sincronizzazione di Thread e Processi.

WaitForSingleObject

• 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 l’indicazione del motivo della terminazione (es. Timeout)

Page 12: Concorrenza e Sincronizzazione di Thread e Processi.

ReleaseMutex

• Funzione: rilascio (unlock) di un Mutex precedentemente occupato

BOOL ReleaseMutex(HANDLE hMutex)

• hMutex: il mutex da rilasciare

• Restituisce TRUE in caso di successo

Page 13: Concorrenza e Sincronizzazione di Thread e Processi.

Stati degli Handle e WaitForSingleObject

• Gli handle sono associati a “eventi di sincronizzazione”, in base ai quali possono transire fra due possibili stati:– Signaled– unsignaled

Handleunsignaled

Handlesignaled

WaitForSingleObject bloccata

[evento di sincronizzazione]

WaitForSingleObject eseguita

Page 14: Concorrenza e Sincronizzazione di Thread e Processi.

Handle e WaitForSingleObjectCaso dei Mutex

Handle Mutexunsignaled

Handle Mutexsignaled

WaitForSingleObject bloccata

[evento di sincronizzazione]ReleaseMutex(…)

WaitForSingleObject eseguita

CreateMutex(…,FALSE,…)

Page 15: Concorrenza e Sincronizzazione di Thread e Processi.

Handle e WaitForSingleObjectCaso di Thread/Processi

Handle threadunsignaled

Handle threadsignaled

WaitForSingleObject bloccata

[evento di sincronizzazione][terminazione del thread/processo]

WaitForSingleObject eseguita

CreateProcess(…)CreateThread(…)

Page 16: Concorrenza e Sincronizzazione di Thread e Processi.

Il nome degli oggetti

• Perché è possibile dare un nome ad un oggetto come un Mutex?– Dare un nome ad un oggetto significa dare visibilità

globale all’oggetto– 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 dell’oggetto esistente

Page 17: Concorrenza e Sincronizzazione di Thread e Processi.

Handle table dei processi e object manager globale

Processo B

H.T.

Object Manager Oggetto 1 Oggetto 2 Oggetto 3 Oggetto 4

Processo A

H.T.

Processo C

H.T.

Gestore unico degli oggetti: li crea, cancella, li contiene, ecc….

Page 18: Concorrenza e Sincronizzazione di Thread e Processi.

Condivisione 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

Page 19: Concorrenza e Sincronizzazione di Thread e Processi.

Coordinamento 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 l’evento (e lo segnala) viene detto “observer”

• Il processo che riceve l’evento (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

Page 20: Concorrenza e Sincronizzazione di Thread e Processi.

Handle e WaitForSingleObjectCaso degli Eventi

Handle eventounsignaled

Handle eventosignaled

WaitForSingleObject bloccata

[evento di sincronizzazione]SetEvent(...)

WaitForSingleObject eseguita

CreateEvent(…)

Page 21: Concorrenza e Sincronizzazione di Thread e Processi.

CreateEvent• Funzione: creazione di un nuovo oggetto evento o connessione ad uno

esistente

• HANDLE CreateEvent(LPSECURITY_ATTRIBUTES lpEventAttributes,BOOL bManualResetBOOL bInitialStateLPCTSTR lpName);

• lpEventAttributes: attributi di sicurezza• bManualReset: gestione manuale del reset (vedere ResetEvent)• bInitialOwner: se true, l’evento risulta già segnalato alla creazione• lpName: nome simbolico dell’oggetto

• Restituisce lo handle dell’evento creato (o connesso)

Page 22: Concorrenza e Sincronizzazione di Thread e Processi.

SetEvent

• Funzione: segnalazione di un evento

BOOL SetEvent(HANDLE hEvent)

• hEvent: l’evento da segnalare

• Restituisce TRUE in caso di successo