Prova teorica 2014.06.16

From Sistemi Operativi
Revision as of 16:11, 5 December 2016 by S.G (talk | contribs) (Esercizio monitor e message passing)
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to navigation Jump to search

Testo: [1]

Esercizio c.1

Testo esercizio

Scrivere il monitor rendezvous che consente ai processi di sincronizzarsi e scambiare dati. Ogni processo chiama la procedure entry rendezvous.sync specificando due parametri: il numero dei processi con i quali il processo corrente vuole sincronizzarsi e un vettore di ugual numero di interi. Il primo elemento e' inizializzato con il valore conferito dal processo chiamante. I processi devono coordinarsi con altri che abbiano chiesto di sincronizzarsi con un ugual numero di processi. Quindi, se e quando N processi hanno chiamato la rendezvous.sync chiedendo la sincronizzazione con N processi, tutti N vengono riattivati. Il vettore passato come secondo parametro deve contenere i valori conferiti dagli N processi, uno in ogni elemento del vettore, seguendo l'ordine di chiamata della rendezvous.sync.

es. P1: int v1[]={42,0,0}; rendezvous.sync(3,v1) …. P1 si blocca....

P2: int v[]={314,0,0}; rendezvous.sync(3,v) …. P2 si blocca....

P3: int vv[]={1,0}; rendezvous.sync(2,vv) …. P3 si blocca....

P4: int q[]={13,0,0}; rendezvous.sync(3,q) … P4 sblocca anche P1 e P2. Il secondo paramentro per tutti e tre avra' valore [42,314,13] ….P3 si sblocchera' se e quando un altro processo chiamera' rendezvous.sync con primo parametro 2.

#define SIZE N

monitor rendezvous {
	generic_type count[];
	condition w[];
	
	void rendezvous (void){
		int i;
		count = new generic_type[SIZE];
		w = new condition[SIZE];
		for(i=0; i<SIZE; i++)
			count[i] = new List[];
	}
	
	procedure entry sync(int np, int vp[]){
		int i, n;
		count[np].append(vp[0]);
		n = len(count[np]);
		if(n == np){
			// Sblocca tutti i processi con richiesta np
			for(i=0; i < n; i++){
				count[np].remove();
				w[np].signal();
			}
		}
		else if(n < np){
			// Blocca processo
			w[np].wait();
		}
	}
}

S.G (talk) 16:11, 5 December 2016 (CET)

Esercizio c.2

Testo esercizio

Usando semafori implementare un emulatore di un servizio di message passing asincrono. Occorre quindi implementare le primitive:

void asend(msg m, pid_t dst)

msg arecv(pid_t sender)

facendo uso di semafori (generali, fifo). (e' presente una chiamata getpid() che fornisce il pid del chiamante). La asend riceve da un mittente specificato (non e' richiesta la gestione della ricezione da qualunque processo).

/*
 * Assumendo che non ci sia limite di grandezza, definisco la seguente
 * struttura buffer tridimensionale, in cui le righe rappresentano i pid
 * dei processi mittenti e le colonne i pid dei processi destinatari.
 * Ad esempio buffer[X][Y] indica il buffer utilizzato dal processo X
 * (il cui pid è X) come mittente e dal processo Y come destinatario.
 * La terza dimensione, verrà utilizzata per la scrittura e lettura di determinati
 * messaggi nel buffer. 
 * 
 * La struttura front e rear vengo utilizzate come nel problema dei produttori/consumatori
 * per saper in quale punto poter scrivere e leggere nel buffer.
 * 
 * La struttura len[X][Y] indica la lunghezza del buffer utilizzata dal processo X (mittente)
 * e Y (destinatario).
 */
msg buffer[][][] = new msg[][][];	
int front[][];	// Assumendo che ogni elemento sia inizilizzato a 0
int rear[][];	// Assumendo che ogni elemento sia inizializzato a 0
Semaphore len[][] = new Semaphore[][];	// Assumendo che ogni elemento sia inizializzato a 0

void asend(msg m, pid_t dst){
	pid_t sen = getpid();
	int f = front[sen][dst]++;
	buffer[sen][dst][f] = m;
	len[sen][dst].V();
}

msg arecv(pid_t sender){
	pid_t dst = getpid();
	len[sender][dst].P();
	int r = rear[sender][dst]++;
	return buffer[sender][dst][r];
}

Si potrebbe anche gestire il caso un processo invia un messaggio a più processi e la ricezione da qualunque processo. S.G (talk) 16:11, 5 December 2016 (CET)