Difference between revisions of "ProvaTeoria 2011.07.25"

From Sistemi Operativi
Jump to navigation Jump to search
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