Difference between revisions of "ProvaTeorica 2012.06.15"
Jump to navigation
Jump to search
(3 intermediate revisions by 2 users not shown) | |||
Line 1: | Line 1: | ||
<h1>http://www.cs.unibo.it/~renzo/so/compiti/2012-06-15.tot.pdf</h1> | <h1>http://www.cs.unibo.it/~renzo/so/compiti/2012-06-15.tot.pdf</h1> | ||
− | + | ||
+ | |||
+ | <syntaxhighlight lang="C"> | ||
+ | /* | ||
+ | * URL: http://www.cs.unibo.it/~renzo/so/compiti/2012-06-15.tot.pdf | ||
+ | * author: Tommaso Ognibene | ||
+ | */ | ||
+ | |||
+ | monitor palindrome5 | ||
+ | { | ||
+ | // Struttura che rappresenta i numeri bloccati | ||
+ | typedef struct | ||
+ | { | ||
+ | condition C; | ||
+ | int N; | ||
+ | } Stopped; | ||
+ | |||
+ | Stopped stopped[10]; | ||
+ | for (int i = 0; i < 10; i++) | ||
+ | stopped[i].N = 0; | ||
+ | int n = 0; | ||
+ | int palindrome[10]; | ||
+ | repeated = {} // Python-like dictionary | ||
+ | |||
+ | procedure entry synch(int index) | ||
+ | { | ||
+ | // Se ho raggiunto la lunghezza del palindromo | ||
+ | if (n == 10) | ||
+ | { | ||
+ | // Azzero le variabili | ||
+ | n = 0; | ||
+ | repeated = {}; | ||
+ | } | ||
+ | // [Case 1] parte sinistra del palindromo | ||
+ | if (n < 5) | ||
+ | { | ||
+ | // Se il numero e' gia' stato inserito | ||
+ | if (repeated[index]) | ||
+ | { | ||
+ | // Mi fermo e attendo di essere sbloccato | ||
+ | stopped[index].N++; | ||
+ | stopped[index].C.wait(); | ||
+ | stopped[index].N--; | ||
+ | } | ||
+ | palindrome[n++] = index; | ||
+ | repeated[index] = true; | ||
+ | } | ||
+ | // [Case 2] parte destra del palindromo | ||
+ | else | ||
+ | { | ||
+ | int number = palindrome[n - 5]; | ||
+ | /* [Case 1] Esiste (almeno) un numero in attesa che corrisponde al numero che | ||
+ | si deve inserire. Lo riattivo. In questo modo evito la starvation. */ | ||
+ | if (stopped[number].N > 0) | ||
+ | { | ||
+ | stopped[number].C.signal(); | ||
+ | // Mi fermo e attendo di essere sbloccato | ||
+ | stopped[index].N++; | ||
+ | stopped[index].C.wait(); | ||
+ | stopped[index].N--; | ||
+ | } | ||
+ | /* [Case 2] Non esiste un numero in attesa che corrisponde al numero che | ||
+ | si deve inserire. Inoltre l'attuale non corrisponde al numero che | ||
+ | si deve inserire. */ | ||
+ | else if (number != index) | ||
+ | { | ||
+ | // Mi fermo e attendo di essere sbloccato | ||
+ | stopped[index].N++; | ||
+ | stopped[index].C.wait(); | ||
+ | stopped[index].N--; | ||
+ | } | ||
+ | palindrome[n++] = index; | ||
+ | } | ||
+ | } | ||
+ | } | ||
+ | </syntaxhighlight> | ||
+ | |||
+ | Esercizio del professore da rivedere | ||
+ | |||
+ | |||
+ | <syntaxhighlight lang="C"> | ||
+ | condition c[10]; /* current != -1 && ((pali && !i in seq) || (ndrome && seq[n]==i)) */ | ||
+ | int current=-1; | ||
+ | boolean waiting[10]; | ||
+ | boolean pali=True; | ||
+ | boolean ndrome=False; | ||
+ | int seq[5]; | ||
+ | int n=0; | ||
+ | |||
+ | procedure entry synch(i) { | ||
+ | waiting[i]=True; | ||
+ | if(current==i) { | ||
+ | current=-1; | ||
+ | if(pali) { | ||
+ | if(n==4) ndrone=True, pali = False; | ||
+ | if(x=anynotin(seq, n, waiting)) | ||
+ | c[x].signal(); | ||
+ | } else { | ||
+ | c[seq[n]].signal; | ||
+ | if(n==0) ndrone=False, pali=True; | ||
+ | |||
+ | } | ||
+ | } | ||
+ | if(current!=-1 || pali && cerca(i, seq, n)!=0 || (ndrome && n!=4)) | ||
+ | c[i].wait(); | ||
+ | if(pali) | ||
+ | seq[n++]==i; | ||
+ | else | ||
+ | n--; | ||
+ | current=i; | ||
+ | waiting[i]=False; | ||
+ | } | ||
+ | </syntaxhighlight> | ||
+ | |||
+ | |||
+ | |||
+ | == Esercizio c.2 == | ||
+ | |||
+ | |||
+ | <syntaxhighlight lang="Python"> | ||
+ | /* | ||
+ | Esercizio c.2: Implementare facendo uso di un processo server e usando le asend() e areceive() le seguenti primitive | ||
+ | di comunicazione: | ||
+ | sx2send(m,dest1,dest2); Invia il messaggio m o a dest1 o a dest2 (ma non ad entrambi) | ||
+ | m = sx2receive(sender); Riceve un messaggio in maniera sincrona. | ||
+ | il mittente e il destinatario devono riattivarsi solo quando il destinatario ha ricevuto il messaggio. | ||
+ | */ | ||
+ | |||
+ | def sx2send(m,dest1,dest2): | ||
+ | asend(SND,getpid(),dest1,dest2,m),server) | ||
+ | arecv(server); | ||
+ | |||
+ | def(sx2receive(sender): | ||
+ | asend((RECV,getpid(),sender,NULL,NULL),server) | ||
+ | return arecv(server) | ||
+ | |||
+ | process server: | ||
+ | waiting=Set({}) | ||
+ | pending=[] | ||
+ | while(True): | ||
+ | (tag,proc,pi1,p2,m)=arecv(*) | ||
+ | if(TAG==SND) | ||
+ | if p1 in waiting: | ||
+ | asend(m,p1) | ||
+ | asend(ACK,proc) | ||
+ | waiting-={p1} | ||
+ | else if p2 in waiting: | ||
+ | asend(m,p2) | ||
+ | asend(ACK,proc) | ||
+ | waiting-={p2} | ||
+ | else pending.append((proc,m,p1,p2)) | ||
+ | else: #TAG==RECV | ||
+ | if(px,mx,p1x,p2x)=searchpending(pending,sender): | ||
+ | #cerca il primo che ha sender come uno dei destinatari | ||
+ | #ed elimina l'elemento dalla sequenza | ||
+ | asend(mx,sender) | ||
+ | asend(ACK,mx) | ||
+ | else: | ||
+ | waiting+={sender} | ||
+ | </syntaxhighlight> |
Latest revision as of 16:23, 14 April 2014
http://www.cs.unibo.it/~renzo/so/compiti/2012-06-15.tot.pdf
/*
* URL: http://www.cs.unibo.it/~renzo/so/compiti/2012-06-15.tot.pdf
* author: Tommaso Ognibene
*/
monitor palindrome5
{
// Struttura che rappresenta i numeri bloccati
typedef struct
{
condition C;
int N;
} Stopped;
Stopped stopped[10];
for (int i = 0; i < 10; i++)
stopped[i].N = 0;
int n = 0;
int palindrome[10];
repeated = {} // Python-like dictionary
procedure entry synch(int index)
{
// Se ho raggiunto la lunghezza del palindromo
if (n == 10)
{
// Azzero le variabili
n = 0;
repeated = {};
}
// [Case 1] parte sinistra del palindromo
if (n < 5)
{
// Se il numero e' gia' stato inserito
if (repeated[index])
{
// Mi fermo e attendo di essere sbloccato
stopped[index].N++;
stopped[index].C.wait();
stopped[index].N--;
}
palindrome[n++] = index;
repeated[index] = true;
}
// [Case 2] parte destra del palindromo
else
{
int number = palindrome[n - 5];
/* [Case 1] Esiste (almeno) un numero in attesa che corrisponde al numero che
si deve inserire. Lo riattivo. In questo modo evito la starvation. */
if (stopped[number].N > 0)
{
stopped[number].C.signal();
// Mi fermo e attendo di essere sbloccato
stopped[index].N++;
stopped[index].C.wait();
stopped[index].N--;
}
/* [Case 2] Non esiste un numero in attesa che corrisponde al numero che
si deve inserire. Inoltre l'attuale non corrisponde al numero che
si deve inserire. */
else if (number != index)
{
// Mi fermo e attendo di essere sbloccato
stopped[index].N++;
stopped[index].C.wait();
stopped[index].N--;
}
palindrome[n++] = index;
}
}
}
Esercizio del professore da rivedere
condition c[10]; /* current != -1 && ((pali && !i in seq) || (ndrome && seq[n]==i)) */
int current=-1;
boolean waiting[10];
boolean pali=True;
boolean ndrome=False;
int seq[5];
int n=0;
procedure entry synch(i) {
waiting[i]=True;
if(current==i) {
current=-1;
if(pali) {
if(n==4) ndrone=True, pali = False;
if(x=anynotin(seq, n, waiting))
c[x].signal();
} else {
c[seq[n]].signal;
if(n==0) ndrone=False, pali=True;
}
}
if(current!=-1 || pali && cerca(i, seq, n)!=0 || (ndrome && n!=4))
c[i].wait();
if(pali)
seq[n++]==i;
else
n--;
current=i;
waiting[i]=False;
}
Esercizio c.2
/*
Esercizio c.2: Implementare facendo uso di un processo server e usando le asend() e areceive() le seguenti primitive
di comunicazione:
sx2send(m,dest1,dest2); Invia il messaggio m o a dest1 o a dest2 (ma non ad entrambi)
m = sx2receive(sender); Riceve un messaggio in maniera sincrona.
il mittente e il destinatario devono riattivarsi solo quando il destinatario ha ricevuto il messaggio.
*/
def sx2send(m,dest1,dest2):
asend(SND,getpid(),dest1,dest2,m),server)
arecv(server);
def(sx2receive(sender):
asend((RECV,getpid(),sender,NULL,NULL),server)
return arecv(server)
process server:
waiting=Set({})
pending=[]
while(True):
(tag,proc,pi1,p2,m)=arecv(*)
if(TAG==SND)
if p1 in waiting:
asend(m,p1)
asend(ACK,proc)
waiting-={p1}
else if p2 in waiting:
asend(m,p2)
asend(ACK,proc)
waiting-={p2}
else pending.append((proc,m,p1,p2))
else: #TAG==RECV
if(px,mx,p1x,p2x)=searchpending(pending,sender):
#cerca il primo che ha sender come uno dei destinatari
#ed elimina l'elemento dalla sequenza
asend(mx,sender)
asend(ACK,mx)
else:
waiting+={sender}