ProvaTeorica 2013.01.24
Esercizio C1: (a) Scrivere un monitor nmbb che realizzi un buffer limitato (di ampiezza BUFSIZE) che consenta alle chiamate write (inserimento nel buffer) e read (lettura da buffer) di operare su vettori di piu' elementi. In particolare l'interfaccia delle procedure entry da implementare e' la seguente: procedure entry write(int n, struct elem *v); procedure entry read(int m, struct elem *w); se n o m sono maggiori di BUFSIZE le funzioni non devono fare nulla (caso di errore). La funzione write deve attendere che ci sia spazio nel buffer per inserire n elementi (il vettore v conterra' n elementi). Solo quando e' possibile completare l'operazione vengono inseriti tutti gli elementi di v nel buffer. La funzione read attende che vi siano almeno m elementi nel buffer quindi estrae dal buffer (in ordine FIFO) m elementi e li copia nel vettore w . (b) sono possibili casi di deadlock? (motivare dettagliatamente la risposta)
La mia Soluzione:
read(): legge dalla coda un elemento senza rimuoverlo
queue(elem v,int n): inserisce nella coda n elementi v;
dequeue(int n): legge n elementi dalla coda e li rimuove;
monitor mnbb{
conditon oktowrite, oktoread;
queue qwrite,qread;
procedure entry write(int n, struct elem *v){
if(n > BUFSIZE){
return(ERROR);
}
if( n > (BUFSIZE - buff.lengh)){
qwrite.queue( n, 1 );
oktowrite.wait();
}
buff.queue( v, n );
if(qread.read() <= buff.lengh){
qread.dequeue(1);
oktoread.signal();
}
}
procedure entry read(int m, struct elem *w){
if(m > BUFSIZE){
return(ERROR);
}
if(m > buff.lengh){
qread.queue( m, 1 );
oktoread.wait();
}
w = buff.dequeue(m);
if(qwrite.read() <= (BUFSIZE - buff.lengh)){
qwrite.dequeue(1);
oktowirte.signal();
}
}
}
- Midolo
monitor nmbb{
queue buffer;
condition oktowrite;
condition oktoread;
/* assumiamo che essendo un buffer limitato ci sia un solo processo che vuole scrivere e un solo processo che vuole leggere */
int N, M;
procedure entry write(int n, struct elem *v){
if(n>BUFSIZE) return;
N=n;
if((BUFSIZE - buffer.len) < N)
oktowrite.wait();
for(i=0; i<N; i++)
buffer.enqueue(v[i]);
if(buffer.len >= M)
oktoread.signal();
}
procedure entry read(int m, struct elem *w){
if(m>BUFSIZE) return;
M=m;
if((BUFSIZE - buffer.len) < M)
oktoread.wait();
for(i=0; i<M; i++)
w[i] = buffer.dequeue;
if((BUFSIZE - buffer.len) >= N)
oktowrite.signal();
}
}
Si può verificare deadlock. Esempio: un lettore vuole leggere un tot di elementi, ma quelli presenti non sono sufficienti. Uno scrittore a sua volta non può più scrivere un certo numero di elementi in quanto il buffer è parzialmente occupato. Lo scrittore aspetterà che il lettore legga; il lettore aspetterà invece lo scrittore: deadlock.
L'eventualità che si verifichi deadlock tuttavia è contemplata dalla traccia, come fa capire il punto b)
Gabriele e Giulia