Академический Документы
Профессиональный Документы
Культура Документы
Sincronizzazione di processi e
thread (2)
Meccanismi di sincronizzazione
Semafori di Dijkstra
Inventati nel 1960s
Meccanismo concettuale: nessuna
implementazione specificata
Meccanismo di sincronizzazione di base nei
sistemi operativi
Definizione di Dijkstra
Una variabile intera non negativa che pu essere
cambiata o testata da due funzioni atomiche
- verhoog (incrementa)
= up = signal =post
Tipi di Semafori
Binari:
Valori 0 e 1
Usati per la mutual exclusion (mutex)
Possono essere utilizzati per il signaling
V(s): [s = s + 1]
Implementare i Semafori
Due modalit distinte:
busy waiting (spinlock): la CPU controlla
attivamente il verificarsi della condizione di
accesso alla sezione critica
scalabile, veloce
CPU-intensive
adatto per attese brevi (accesso a memoria)
void Wait(semaforo S) {
! S.valore--;
! while (S.valore < 0) {
! !
! }
}
void Signal(semaforo S) {
! S.valore++;
! }
pi lento
adatto per attese lunghe (I/O)
Operating Systems and Distributed Systems
typedef struct {
! int valore;
} semaforo;
typedef struct {
! int valore;
! struct processo *p;
} semaforo;
void Wait(semaforo S) {
disableInterrupts();
! S.valore--;
! while (S.valore < 0) {
! !
enableInterrupts();
disableInterrupts();
! }
enableInterrupts();
}
void Wait(semaforo S) {
! S.valore--;
! if (S.valore < 0) {
! !
<accoda processo a S.p>;
! !
block();
! }
}
KERNEL
mette il
processo in
stato di pronto
Un esempio reale:
Semafori in MANTIS OS
void mos_sem_wait(mos_sem_t *s)
{
handle_t int_handle;
int_handle = mos_disable_ints();
int_handle = mos_disable_ints();
s->val--;
// Post a unit and wake-up the next waiting thread
s->val++;
mos_enable_ints(int_handle);
}
P(s)
Operating Systems and Distributed Systems
mette il
processo in
stato di attesa
void Signal(semaforo S) {
! S.valore++;
! if (S.valore <= 0) {
! !
<estrai un processo p da S.p>;
! !
wakeup(p);
! }
}
void Signal(semaforo S) {
disableInterrupts();
! S.valore++;
enableInterrupts();
! }
V(s)
Operating Systems and Distributed Systems
semaphore_t mutex = 1;
int var_condivisa;
void worker() {
while(1) {
Wait(mutex);
var_condivisa ++;
Signal(mutex);
}
}
A
B
A
B
B e D alla
barriera
14
Thread #1
Thread #2
...
...
Signal(ready1);
Wait(ready2);
...
...
...
...
Signal(ready2);
Wait(ready1);
...
...
Variabili Globali
semaphore ready1 = 0;
semaphore ready2 = 0;
Device driver
Controller
...
...
Signal(busy);
Wait(done);
...
...
...
...
Wait(busy);
Signal(done);
...
...
Variabili Globali
semaphore busy = 0;
semaphore done = 0;
named semaphores
unnamed semaphores.
unnamed semaphores.
Un unnamed semaphore anonimo.
Collocato in una regione di memoria condivisa fra pi
threads ( thread-shared semaphore) o pi processi
(process-shared semaphore).
Thread-shared semaphore: esempio, una variabile globale.
Process-shared semaphore: esempio shared memory
region (e.g., in System V shared memory segment creato
con semget(), oppure un shared memory object POSIX
ottenuto mediante shm_open()).
Semafori POSIX
Prototipi definiti in semaphore.h.
Dichiarazione:
sem_t sem_name;
Inizializzazione:
int sem_init(sem_t *sem,
int pshared,
unsigned int value);
!! sem puntatore al semaforo
!! pshared =1 se shared con processi fork()ed.
!! value valore iniziale del semaforo (1 per sem binari)
Esempio:
sem_init(&sem_name, 0, 10);
Semafori POSIX
Attesa su semaforo:
int sem_wait(sem_t *sem);
Semafori POSIX
Interrogare il valore del semaforo
int sem_getvalue(sem_t *sem, int *valp);
esempio:
sem_wait(&sem_name);
Esempio:
sem_post(&sem_name);
Operating Systems and Distributed Systems
Distruzione semaforo:
int sem_destroy(sem_t *sem);
p_sembarr.c!
Producer
Consumer
Full Pool
Variabili condivise
If buffer== PIENO
il produttore non pu inserire
27
const int n;
typedef Item;
Item buffer[n];
int in = 0, out = 0,
counter = 0;
Counter ++;
Counter --;
Produttore
Consumatore
Item pitm;
while (1) {
while (counter == n)
;
buffer[in] = pitm;
in = (in+1) % n;
counter ++;
}
Item citm;
while (1) {
while (counter == 0)
;
citm = buffer[out];
out = (out+1) % n;
counter --;
28
typedef struct {
! char buf[BSIZE];
! int occupied;
! int nextin, nextout;
#ifdef __APPLE__
! semaphore_t mutex ;//control access to critical region
! semaphore_t more ; //counts full buffer slots
! semaphore_t less ; //counts empty buffer slots
#else
! sem_t mutex;//control access to critical region
! sem_t more; //counts full buffer slots
! sem_t less; //counts empty buffer slots
#endif
!
} buffer_t;
buffer_t buffer;
29
30
31
32
Produttore - consumatore
!
_sem_wait(&(buffer.more));!
//decrement full count
!
_sem_wait(&(buffer.mutex));!
//enter critical region
!
!
printf("consumer executing.\n");
!
!
item = buffer.buf[buffer.nextout++];//take item from buffer!
!
!
buffer.nextout %= BSIZE;
!
buffer.occupied--;
!
!
_sem_signal(&(buffer.mutex));!
//leave critical region
!
_sem_signal(&(buffer.less));!
//signals the producer and increments empty count
!
!
printf("%c\n",item);! !
//prints the item
!
}
printf("consumer exiting.\n");
pthread_exit(0);
33
Lettori e scrittori
Lettori e scrittori
Reader
Reader
Reader
Reader
Reader
Reader
Reader
Reader
Writer
Writer
Writer
Writer
Writer
Writer
Writer
Writers
Readers
Shared Resource
Lettori e scrittori
Lettori e scrittori
Writer
Writer
Writer
Writer
Writer
Writer
Writer
Reader
Reader
Reader
Reader
Reader
Reader
Reader
Reader
Writer
Writer
Writer
Writer
Writer
Writer
Reader
Reader
Reader
Reader
Reader
Reader
Reader
Reader
Writer
Shared Resource
Shared Resource
Lettori e scrittori
39