Anteprima
Vedrai una selezione di 10 pagine su 151
Appunti Sistemi operativi - parte 5 Pag. 1 Appunti Sistemi operativi - parte 5 Pag. 2
Anteprima di 10 pagg. su 151.
Scarica il documento per vederlo tutto.
Appunti Sistemi operativi - parte 5 Pag. 6
Anteprima di 10 pagg. su 151.
Scarica il documento per vederlo tutto.
Appunti Sistemi operativi - parte 5 Pag. 11
Anteprima di 10 pagg. su 151.
Scarica il documento per vederlo tutto.
Appunti Sistemi operativi - parte 5 Pag. 16
Anteprima di 10 pagg. su 151.
Scarica il documento per vederlo tutto.
Appunti Sistemi operativi - parte 5 Pag. 21
Anteprima di 10 pagg. su 151.
Scarica il documento per vederlo tutto.
Appunti Sistemi operativi - parte 5 Pag. 26
Anteprima di 10 pagg. su 151.
Scarica il documento per vederlo tutto.
Appunti Sistemi operativi - parte 5 Pag. 31
Anteprima di 10 pagg. su 151.
Scarica il documento per vederlo tutto.
Appunti Sistemi operativi - parte 5 Pag. 36
Anteprima di 10 pagg. su 151.
Scarica il documento per vederlo tutto.
Appunti Sistemi operativi - parte 5 Pag. 41
1 su 151
D/illustrazione/soddisfatti o rimborsati
Disdici quando
vuoi
Acquista con carta
o PayPal
Scarica i documenti
tutte le volte che vuoi
Estratto del documento

Ricapitolando

Abbiamo che in questa soluzione dobbiamo stare attenti a ricercare la prima locazione vuota per i produttori per poter produrre, una volta trovata non ci si deve dimenticare di mettere lo stato di quella locazione in uso in quanto se ce lo si dimentica accade che non sarà possibile andare a trovare il buffer pieno vuoto, dobbiamo poi andare a segnalare eventuali altri processi della stessa tipologia e quindi se stiamo nei produttori segnaliamo i produttori altrimenti i consumatori perché a questo punto avremo trovato una locazione che non collidere e che quindi non starà in competizione con altri produttori o consumatori e quindi possiamo andare a produrre o consumare al di fuori della sezione critica. Una volta fatto questo possiamo andare a segnalare gli eventuali produttori o consumatori.

N.B All'esame ci sarà un'alternanza di esercizi che dovranno essere risolti con pool di buffer a coda circolare o pool di buffer a vettore stato.

questo sarà esplicitamente richiesto nella traccia e se non è richiesto verràsicuramente delineato il tipo di sincronizzazione che si vuole e quindi ci potrebbero essere delle varianti delproblema. Nel caso ad esempio esca nella traccia un solo produttore o un solo consumatore ed n produttorio consumatori dobbiamo andare a cambiare l’utilizzo dei semafori in quanto i semafori che abbiamo vistoora sono per la competizione tra più produttori o più consumatori e quindi se si ha un solo produttore osolo un consumatore non abbiamo nessuna competizione.

Vediamo ora degli esercizi di lettore e scrittore. In questo caso abbiamo dei processi che sono- Lettori -> leggono il valore di un messaggio su una risorsa condivisa- Scrittori -> Scrivono un messaggio su di una risorsa condivisa

Questo problema ad un primo sguardo lo possiamo considerare simile a quello dei produttori econsumatori in quanto anche lì ci sono dei processi che

leggono o scrivono su aree di memoria condivisa ma c'è una differenza sostanziale dovuta al fatto che i lettori possono contemporaneamente andare a leggere la risorsa condivisa mentre gli scrittori non possono andare a scrivere contemporaneamente sulla risorsa condivisa e un processo scrittore ed un processo lettore ovviamente avranno accesso esclusivo alla risorsa. Sostanzialmente abbiamo che i lettori possono fare quello che vogliono in quanto non modificano lo stato di una risorsa e quindi possono andare in contemporanea a leggere la risorsa condivisa mentre scrittori tra di loro e scrittori e lettori non possono accedere in contemporanea alla risorsa condivisa e quindi vi devono accedere in mutua esclusione. Le problematiche che si possono presentare sono di Starvation che come abbiamo detto è un fenomeno di attesa indefinita dei processi che accedono ad una risorsa condivisa. Abbiamo tre possibili soluzioni:

  1. lettori e scrittori con Starvation degli scrittori -> in

In questo caso abbiamo che uno scrittore che vuole andare ad accedere alla risorsa condivisa potrebbe attendere in modo indefinito se ad esempio c'è uno stream di lettori che arriva più o meno veloce.

2) lettori e scrittori con Starvation di entrambi -> in questo caso abbiamo una certa fairness tra le due tipologie di processi anche se con questa soluzione potrebbe capitare in alcune condizioni specifiche che vengano ad essere penalizzati i lettori invece che gli scrittori.

3) Fairness perfetta (soluzione che non faremo) -> in cui si ha un ordinamento con una coda di richieste in cui lettori e scrittori mandano richieste ad uno scheduler il quale andrà ad ordinarle in modo equo per poter dare lo stesso tempo di esecuzione sia ai lettori che agli scrittori.

Per poter risolvere il problema 1 e quindi quello per cui si ha un'applicazione con lettori e scrittori con Starvation degli scrittori si usa la variabile condivisa che conta il numero di lettori che

accedonocontemporaneamente alla risorsa; questa variabile condivisa serve per poter capire se c'è almeno un lettore in attesa di leggere perché in tal caso si avrà che gli scrittori non potranno accedere. Questa soluzione per tale ragione ci porta alla Starvation degli scrittori. In questa soluzione si usano sempre due semafori: uno per gestire l'accesso alla variabile condivisa NUMERO_LETTORI che deve essere incrementata e decrementata dai lettori, e poi un altro semaforo per garantire la mutua esclusione tra i processi lettori e scrittori e tra gli scrittori stessi. Andiamo ad implementarla scrivendo l'header e le procedure. Per quanto riguarda il main, non lo vedremo in quanto è semplice da scrivere perché dovremmo banalmente andare ad usare shared memory e semafori come fatto fino ad ora. N.B. Tutte le soluzioni codice che abbiamo visto e che vedremo si trovano nel Repository GitHub. Cominciamo con il vedere il file header.h. Dobbiamo andare```html

A definire due semafori che chiamiamo MUTEXL e SYNCH e poi definiamo NUM_VOLTE che rappresenta il numero di volte che va a leggere o scrivere un lettore o uno scrittore. In questo caso abbiamo bisogno di una struttura dati che deve essere acceduta tra i lettori e scrittori e quindi ci andiamo a definire questa struttura che deve essere sempre allocata tramite shared memory e poi dobbiamo andare a definirci sempre l'indice del semaforo su cui vogliamo andare ad effettuare la Wait e la Signal. Usiamo in questo esempio un typedef per andare a definire un tipo di dato long con msg, in questo modo potremmo riferirci al tipo long per il tipo di dato che andremo ad usare tra i lettori e scrittori. Abbiamo bisogno poi di un'altra struttura che va ad inserire oltre a questo messaggio, questo intero, questo singolo buffer anche il numero di lettori e quindi la variabile condivisa tra i vari lettori che deve essere aggiornata.

```tale che quando scriveremo buffer ciriferiremo ad una struttura che contiene il numero di lettori ed il messaggio e quindi questo valore daleggere e scrivere. I prototipi delle due funzioni Lettore e Scrittore conterranno il tipo int che costituiscel'indice del semaforo sul quale vogliamo effettuare la Wait o la Signal e poi un puntatore alla struttura. Queste due operazioni includeranno la lettura e la scrittura ed altre due funzioni di utilità che potremmoanche andare a scrivere senza usare chiamate a funzione, però abbiamo visto che la lettura e la scritturasono protette da due funzioni, quella di inizio lettura/scrittura e fine lettura/scrittura e quindi prima dipoter leggere/scrivere effettivamente dobbiamo sincronizzarci tra i vari lettori e scrittori con questefunzioni di inizio lettura/scrittura e fine lettura/scrittura e questo lo andremo a fare nel file di procedures. Vediamo ora il file di procedures.c. Come prima cosa copiamoci i soliti include. Andiamo poi adimplementare il Lettore. Al lettore dobbiamo passare l'indice del semaforo, un puntatore a buffer tramite la shared memory attach, questa struttura contiene la variabile NUMERO_LETTORI ed il valore da scrivere o leggere. Questa lettura che possiamo fare semplicemente con una printf deve essere protetta da un inizio lettura dove passiamo il semaforo ed il buffer ed un fine lettura a cui passiamo sempre il semaforo ed il buffer. Queste due funzioni per maggiore leggibilità conviene implementarle separatamente e poi chiamarle. Inizio lettura avrà un semaforo ed un puntatore a buffer e stessi valori avrà la funzione di fine lettura. Per la funzione di inizio lettura prima di poter leggere un lettore deve aumentare il contatore dei lettori che vogliono accedere in lettura all'area di memoria condivisa, questa operazione deve essere fatta in mutua esclusione tra i vari lettori e quindi prima dobbiamo andare a fare una Wait sul semaforo che abbiamo chiamato MUTEXL edopo una Signal sempre sullo stesso semaforo. Dobbiamo poi andare a controllare la condizione del lettore e quindi dobbiamo andare a vedere se c'è almeno un lettore, in tal caso se è il primo lettore bisogna andare a bloccare il buffer per gli scrittori. Mettiamo allora una condizione che se è soddisfatta farà una Wait su SYNCH, questo ci basta per andare a leggere. Nella funzione di fine lettura dobbiamo andare a controllare se siamo l'ultimo lettore ovviamente dopo aver decrementato la variabile ed il contatore del numero di lettori in attesa per la lettura dobbiamo andare a svegliare gli scrittori fino a quando non c'è nessun lettore in quanto stiamo adottando la soluzione con la starvation dei soli scrittori. Dobbiamo quindi andare a proteggere l'istruzione di decremento del contatore con una Wait che garantisce protezione dalla competizione tra i vari lettori, possiamo quindi fare la stessa cosa di prima con Signal_Sem ma in

più dobbiamo andare a svegliare eventuali scrittori che sono in attesa.

Se siamo l’ultimo lettore e quindi numlettori = 0 dobbiamo andare a dire allo scrittore che può andare a scrivere e quindi andiamo a fare una Signal sul semaforo che abbiamo adibito per la sincronizzazione tra lettori e scrittori e scrittori tra di loro.

Dobbiamo quindi fare attenzione a queste due condizioni:

  1. La complessità di questa soluzione è quindi relativa solo ai lettori in quanto lo scrittore non fa niente altro che una wait ed una signal perché sono quelli penalizzati da questa soluzione.
  2. Andiamo ora a vedere come è fatto lo scrittore. La funzione Scrittore abbiamo che farà sempre la scrittura e quindi andremo ad impostare il valore di buffer a valore, questo valore val nell’esercizio visto su GitHub usa un valore del timestamp attuale quando andiamo ad eseguire il codice tramite la funzione in blu sotto.

Nell’esempio in questione possiamo

fare quello che vogliamo anche usare un valore randomico tramite la funzione srand. Nella funzione scrittore abbiamo che la scrittura deve essere sempre protetta da un <inizioscrittura> ed un <fine scrittura>, nel caso in esame gli andiamo a passare il descrittore dell'array semaforico. Vediamo ora come è fatta la funzione InizioScrittura. Tale funzione deve andare a fare una Wait sul semaforo SYNCH, il semaforo degli scrittori, dobbiamo quindi assicurarci che quando andiamo a fare queste due operazioni non ci deve essere nessun lettore e nessun scrittore perché dobbiamo scrivere, una volta scritto dobbiamo andare a rilasciare il semaforo. Lo scrittore praticamente non conta niente ed è penalizzato rispetto ai lettori. Diversamente dai lettori-scrittori con starvation dei soli scrittori vediamo quali sono le modifiche che devono essere fatte per avere una starvation di entrambi i processi. Torniamo all'header che abbiamo scritto prima. Per la starvation di entrambidobbiamo avere che gli scrittori non devono essere penalizzati e quindi uno scrittore quando riesce ad accedere alla sezione critica per poter scrivere deve tener conto anche del numero degli scrittori che sono in attesa. Nella
Dettagli
Publisher
A.A. 2022-2023
151 pagine
SSD Ingegneria industriale e dell'informazione ING-INF/05 Sistemi di elaborazione delle informazioni

I contenuti di questa pagina costituiscono rielaborazioni personali del Publisher Dadox94 di informazioni apprese con la frequenza delle lezioni di Sistemi operativi e studio autonomo di eventuali libri di riferimento in preparazione dell'esame finale o della tesi. Non devono intendersi come materiale ufficiale dell'università Università degli studi di Napoli Federico II o del prof Crotoneo Domenico.