Difference between revisions of "ProvaTeoria 2011.07.25"
Jump to navigation
Jump to search
Stefano 92 (talk | contribs) |
Stefano 92 (talk | contribs) |
||
Line 1: | Line 1: | ||
− | Esercizio 2 | + | ==Esercizio 2== |
<syntaxhighlight lang="C"> | <syntaxhighlight lang="C"> | ||
//siano dati tre processi "stampa" come segue: | //siano dati tre processi "stampa" come segue: | ||
Line 57: | Line 57: | ||
</syntaxhighlight> | </syntaxhighlight> | ||
+ | ==Esercizio 3== | ||
+ | /* | ||
+ | Esercizio 3: Dato un servizio di message passing asincrono (NON completamente asincrono) e senza fare uso di un | ||
+ | server implementare un servizio di message passing sincrono LIFO. (cioe' dati asend/arecv, implementare lssend | ||
+ | lsrecv) | ||
+ | I messaggi possono essere di grandi dimensioni, si chiede quindi che l'implementazione non crei una coda con tutti i | ||
+ | messaggi in attesa di essere ricevuti. | ||
+ | */ | ||
+ | <syntaxhighlight lang="C"> | ||
+ | |||
+ | |||
+ | pid* database=Queue(); | ||
+ | |||
+ | void lssend(int dest,message m) | ||
+ | { | ||
+ | message tmp; | ||
+ | asend(dest,"#"); | ||
+ | do | ||
+ | { | ||
+ | tmp=arecv(dest); | ||
+ | } | ||
+ | while(tmp!="OK"); | ||
+ | asend(dest,"OK") | ||
+ | arecv(dest); | ||
+ | return; | ||
+ | } | ||
+ | |||
+ | |||
+ | message lsrecv(pid sender) | ||
+ | { | ||
+ | message tmp; | ||
+ | pid replier; //replier conterrà il p_id del sender da cui ricevere il messaggio | ||
+ | if (sender!=*) | ||
+ | { | ||
+ | arecv(sender); | ||
+ | replier=sender; //devo sicuramente ricevere da questo sender | ||
+ | } | ||
+ | else | ||
+ | { | ||
+ | asend("BOT",getpid()); //per la lettura del buffer di messaggi | ||
+ | tmp=arecv(*); | ||
+ | if (tmp=="BOT") | ||
+ | { | ||
+ | //coda di messaggi vuota: recupero il primo replier disponibile dal DB | ||
+ | replier=db.dequeue(); | ||
+ | if (replier==NULL) | ||
+ | { | ||
+ | //coda vuota e DB vuoto: il primo messaggio arrivato è quello da ritornare | ||
+ | tmp=arecv(*); | ||
+ | replier=tmp.sender; | ||
+ | } | ||
+ | } | ||
+ | else do | ||
+ | { | ||
+ | //cerco l'ultimo messaggio prima di bottom: metto i sender di tutti gli altri messaggi nel DB | ||
+ | replier=tmp.sender; | ||
+ | tmp=arecv(*); | ||
+ | if (tmp!="BOT") | ||
+ | { | ||
+ | db.enqueue(replier); | ||
+ | replier=tmp.sender; | ||
+ | } | ||
+ | } | ||
+ | while (tmp!="BOT"); | ||
+ | //ho trovato il mio replier | ||
+ | } | ||
+ | asend(replier,"OK"); | ||
+ | tmp=arecv(replier); | ||
+ | asend(replier,"END"); | ||
+ | return tmp; | ||
+ | } | ||
+ | </syntaxhighlight> | ||
-stefano92 | -stefano92 |
Revision as of 12:59, 5 May 2014
Esercizio 2
//siano dati tre processi "stampa" come segue:
//stampa(x):(x=A,T,R) process
//while (true) {
// synchro(x);
// print(x);
//}
//scrivere la fuzione synchro() facendo uso di semafori che consenta di avere in output una sequenza infinita
//di TARATATA (i.e. TARATATATARATATATARATATATARATATATARATATA......)
/*La soluzione prevede l'utilizzo di 3 semafori, uno per ogni lettera (T,A,R). E' presente anche una variabile buflen contenente
la lunghezza della stringa stampata fino ad ora.
L'idea si basa sull'utilizzo di una funzione mutex_print() che, a seconda dell'output generato, libera l'opportuno semaforo.
Le risorse dei semafori vengono poi richieste dai processi.*/
/*definizione variabili di supporto e #define*/
#DEFINE T 0
#DEFINE R 1
#DEFINE A 2
int buflen=0;
/*definizione dei semafori*/
int sem[3];
sem[T]=1;
sem[R]=0
sem[A]=0
/*funzione di supporto: controlla se è arrivato il momento di stampare una R*/
int checkR(int x)
{
if((x-2)%8==0)
return 1;
else return 0;
}
void mutex_print()
{
if (buflen==0) return;
else if (buflen%2!=0)
v(sem[A]);
else if (checkR(buflen))
v(sem[R]);
else v(sem[T]);
return;
}
void synchro(int x)
{
mutex();
p(sem[x]);
buflen++;
}
Esercizio 3
/* Esercizio 3: Dato un servizio di message passing asincrono (NON completamente asincrono) e senza fare uso di un server implementare un servizio di message passing sincrono LIFO. (cioe' dati asend/arecv, implementare lssend lsrecv) I messaggi possono essere di grandi dimensioni, si chiede quindi che l'implementazione non crei una coda con tutti i messaggi in attesa di essere ricevuti.
- /
pid* database=Queue();
void lssend(int dest,message m)
{
message tmp;
asend(dest,"#");
do
{
tmp=arecv(dest);
}
while(tmp!="OK");
asend(dest,"OK")
arecv(dest);
return;
}
message lsrecv(pid sender)
{
message tmp;
pid replier; //replier conterrà il p_id del sender da cui ricevere il messaggio
if (sender!=*)
{
arecv(sender);
replier=sender; //devo sicuramente ricevere da questo sender
}
else
{
asend("BOT",getpid()); //per la lettura del buffer di messaggi
tmp=arecv(*);
if (tmp=="BOT")
{
//coda di messaggi vuota: recupero il primo replier disponibile dal DB
replier=db.dequeue();
if (replier==NULL)
{
//coda vuota e DB vuoto: il primo messaggio arrivato è quello da ritornare
tmp=arecv(*);
replier=tmp.sender;
}
}
else do
{
//cerco l'ultimo messaggio prima di bottom: metto i sender di tutti gli altri messaggi nel DB
replier=tmp.sender;
tmp=arecv(*);
if (tmp!="BOT")
{
db.enqueue(replier);
replier=tmp.sender;
}
}
while (tmp!="BOT");
//ho trovato il mio replier
}
asend(replier,"OK");
tmp=arecv(replier);
asend(replier,"END");
return tmp;
}
-stefano92