Programmazione concorrente

Transcript

Programmazione concorrente
Programmazione concorrente AXO Matteo Guarnerio Programmazione concorrente Riferimento alla slide: AXO -­‐ 03 -­‐ Programmazione concorrente.pdf Per l’implementazione delle funzioni utilizzate si fa riferimento alla libreria: pthread.h Processi e thread possono usare entrambi sia i mutex sia i semafori, poiché queste variabili sono associate a degli handle di sistema operativo, ed ogni processo o thread ne possiede gli indirizzi. Questa è la ragione per cui nelle funzioni riguardanti mutex e semafori, le variabili vengono sempre passate per indirizzo. Differenze tra processi e thread Processi: • La porzione di dati viene copiata da padre in figlio. • Un processo è indipendente (può crashare uno e non termina l’altro) • Non possono scambiare dati, a meno che non si sfruttino pagine di memoria condivise. Thread: • I dati sono condivisi. • Non sono indipendenti l’uno dall’altro (se crasha il processo che li ha generati, terminano tutti). • Possono scambiare dati tra di loro (dati condivisi). Sequenze critiche e mutex Il mutex è un costrutto specializzato per la mutua esclusione. E’ una variabile di tipo: pthread_mutex_t Per utilizzarlo è necessario inizializzarlo con la funzione apposita: pthread_mutex_init(&mutex) Le funzioni per utilizzare un mutex sono: Funzione Azione pthread_mutex_lock(&mutex) Acquisisce un lock sul mutex, se possibile. Altrimenti si mette ad attendere che venga liberato il mutex. pthread_mutex_unlock(&mutex) Sblocca il mutex. Se più thread effettuano un lock sullo stesso mutex, viene assegnato al primo thread arrivato, tutti gli altri si metteranno in attesa che venga liberato il mutex. Se lo stesso thread effettua due lock sullo stesso mutex, senza prima aver fatto un unlock, andrà in deadlock e quindi in sleep_on, attendendo che lo stesso mutex venga rilasciato da lui (programma impallato). 1 Programmazione concorrente AXO Matteo Guarnerio Sincronizzazione e semafori Il semaforo è una variabile di tipo: sem_t Per utilizzarlo è necessario inizializzarlo con la funzione apposita: sem_init(&semaforo, 0, valore) dove zero è lo standard, le opzioni. Il valore al quale è inizializzato il semaforo indica il numero di thread che possono accedere alla sezione critica. Il semaforo assume quindi dei valori, che indicano il numero di risorse disponibili, dai quali possiamo capire se un thread può proseguire nell’elaborazione o si deve fermare: Valore del semaforo Significato > 0 Ci sono risorse disponibili. = 0 Non ci sono risorse disponibili. < 0 Non ci sono risorse disponibili. Indica quanti thread sono in attesa che una risorsa si liberi. Per incrementare e decrementare il valore di un semaforo si usano le seguenti funzioni: Funzione Azione sem_wait(&semaforo) Decrementa il valore del semaforo di 1 sem_post(&semaforo) Incrementa il valore del semaforo di 1 2