Tags:
tag this topic
create new tag
view all tags
---+ Tutti gli esercizi per l'orale [[#esercizi_4][Esercizi da 4 punti]]<br /> [[#esercizi_8][Esercizi da 8 punti]]<br /> [[#esercizi_12][Esercizi da 12 punti]] <a name="esercizi_4"/> ---++ Esercizi da 4 punti Per rispondere, __non__ è concesso consultare libro e dispense <br /><br /><br /><br /> <!-- semafori --> I seguenti tre processi concorrenti condividono due semafori<!--forti no, non importa-->: <br /> <textarea cols="100" rows="11" readonly="readonly"> semaphore U = 3; semaphore V = 0; [Process 1] [Process 2] [Process 3] while(1) { while(1) { while(1) { semWait(U); semWait(V); semWait(V); print("A"); print("B"); print("C"); semSignal(V); semSignal(V); } } } </textarea> <br /> Tenendo presente che l'unica assunzione possibile sul dispatcher è che, prima o poi, dia l'opportunità di andare in esecuzione a tutti i processi, e che nessun altro processo manipola i semafori U e V, stabilire se sia possibile che il numero di caratteri "B" stampati durante l'esecuzione dei tre processi sia 10, e che il numero di caratteri "C" sia 0. <br /><br /><br /><br /> <!-- semafori --> I seguenti due processi concorrenti condividono una variabile ed un semaforo: <br /> <textarea cols="100" rows="10" readonly="readonly"> semaphore S = 1; int X = 4; [Process 1] [Process 2] int Y; int Z; semWait(S); semWait(S); Y = X*2; Z = X+1; X = Y; X = Z; semSignal(S); semSignal(S); </textarea> <br /> Tenendo presente che l'unica assunzione possibile sul dispatcher è che, prima o poi, dia l'opportunità di andare in esecuzione a tutti i processi, e che nessun altro processo manipola né S né X, stabilire se è possibile che X contenga uno dei seguenti valori al termine dell'esecuzione: 8, 9, 10. Stabilire anche se sia possibile che X abbia uno di quei valori in un qualsiasi momento dell'esecuzione combinata dei 2 processi. Cosa cambia se si elimina una delle chiamate a =semSignal=? e se si elimina una delle chiamate a =semWait=? <br /><br /><br /><br /> <!-- paginazione --> Un sistema con gestione paginata semplice della memoria ha indirizzi di 40 bit e pagine di dimensione 16 KiB. Se la memoria è paginabile a partire dall'indirizzo =0x000000a000=, qual è il numero massimo di elementi contenuti nella tabella delle pagine di un processo? Si supponga inoltre che tale tabella sia organizzata in 2 livelli, in modo tale che la _page directory_ (primo livello) sia indirizzata da 10 bit. Quanti bit saranno usati per indirizzare il secondo livello? Quante entry ci saranno, al massimo, tra tutte le tabelle delle pagine (primo e secondo livello) di un processo? <br /><br /><br /><br /> <!-- tempo_di_accesso --> Si consideri una unità disco con una velocità di rotazione di 1000 rivoluzioni al minuto (rpm). La testina, per spostarsi da una traccia alla successiva, impiega 1 ms. Ogni traccia del disco contiene 32 KiB. Si assuma che una porzione di dimensione 2 MiB di un file sia memorizzata sul disco in settori contigui (si intendono contigui anche settori su diverse tracce, per i quali sia sufficiente il semplice spostamento della testina). Indicare qual è il tempo totale, in secondi, necessario per il trasferimento di questi 2 MiB di dati dal disco in memoria principale, nel caso in cui la testina sia posizionata sulla traccia giusta, ma a 5 settori di distanza (su 32 settori totali per traccia) dal settore giusto, che è il primo della traccia stessa. Quanti byte ci sono per ogni settore? <br /><br /><br /><br /> <!-- io_versus_cpu --> Un calcolatore multiprogrammato esegue _N_ processi concorrenti. Ciascun processo ha le medesime caratteristiche ed è strutturato in fasi di attività di lunghezza di _M_ millisecondi. Solo una frazione _0 < C ≤ 0.5_ di questi _M_ millisecondi è passata in attività di I/O, e tale attività è concentrata tutta alla fine di ciascuna fase. Il resto di ogni fase è quindi speso in attività di elaborazione sul processore. Ciascun processo viene eseguito per un totale complessivo di _F_ fasi di attività usando un semplice scheduler round-robin. Ciascun processore agisce su un dispositivo di I/O indipendente da quello su cui operano gli altri processi. Si calcoli il tempo medio di risposta, in ms, nel caso migliore e nel caso peggiore, nel caso in cui i parametri dei processi siano i seguenti: _M_ =10 ms, _N_ =4, _C_ =0.2, _F_ =3. Assumere trascurabile il tempo di switch tra processi. <br /><br /><br /><br /> <!-- io_versus_cpu --> Un calcolatore multiprogrammato esegue _N_ processi concorrenti. Ciascun processo ha le medesime caratteristiche ed è strutturato in fasi di attività di lunghezza di _M_ millisecondi. Solo una frazione _0 < C ≤ 0.5_ di questi _M_ millisecondi è passata in attività di I/O, e tale attività è concentrata tutta alla fine di ciascuna fase. Il resto di ogni fase è quindi speso in attività di elaborazione sul processore. Ciascun processo viene eseguito per un totale complessivo di _F_ fasi di attività usando un semplice scheduler round-robin. Ciascun processore agisce su un dispositivo di I/O indipendente da quello su cui operano gli altri processi. Si calcoli il throughput, in processi al ms, nel caso migliore e nel caso peggiore, nel caso in cui i parametri dei processi siano i seguenti: _M_ =12 ms, _N_ =3, _C_ =0.3, _F_ =4. Assumere trascurabile il tempo di switch tra processi. <br /><br /><br /><br /> <!-- scheduling --> Considerare un insieme di cinque processi P1, P2, P3, P4, P5 con i seguenti tempi di arrivo e tempi di esecuzione in millisecondi: <!--ancora dentro--> <!--ancora dentro--><!--ancora dentro--><!--ancora dentro--><!--ancora dentro--><!--ancora dentro--> <!--ancora dentro--><!--ancora dentro--><!--ancora dentro--><!--ancora dentro--><!--ancora dentro--> <!--ancora dentro--><!--ancora dentro--><!--ancora dentro--><!--ancora dentro--><!--ancora dentro--> <!--ancora dentro--><!--ancora dentro--><!--ancora dentro--><!--ancora dentro--><!--ancora dentro--> <!--ancora dentro--><!--ancora dentro--><!--ancora dentro--><!--ancora dentro--><!--ancora dentro--> | *Processo* | *Tempo di Arrivo* | *Tempo di esecuzione* | | P1 | 2 | 15 | | P2 | 5 | 10 | | P3 | 12 | 7 | | P4 | 9 | 5 | | P5 | 15 | 7 | <!--ancora dentro--> Assegnare questo insieme di processi ad un processore usando l'algoritmo di _scheduling SRT_, fino a quando non terminano tutti. Rispondere alle seguenti domande: * Qual è il tempo medio di turnaround? * Quali sono i processi che non sono serviti subito (ovvero, appena arrivati)? * Qual è il tempo medio di attesa? <br /><br /><br /><br /> <!-- page_replace --> Considerare un sistema con memoria virtuale a paginazione semplice nel quale sono presenti 5 pagine fisiche dedicate ad uno specifico processo utente. Tale processo effettua i seguenti riferimenti alla memoria virtuale: 8, 0, 1, 3, 1, 2, 4, 3, 12. Mostrare le evoluzioni della memoria principale (inizialmente vuota) a seconda del diverso algoritmo di rimpiazzamento usato: FIFO, LRU, clock. <br /><br /><br /><br /> <!-- trad_ind_log --> Si consideri una memoria di 32 byte suddivisa in 8 pagine da 4 byte ciascuna. La page table di un processo in esecuzione è la seguente: <!----> <!----><!--ancora dentro--><!--ancora dentro--><!--ancora dentro--><!--ancora dentro--><!----> <!----><!--ancora dentro--><!--ancora dentro--><!--ancora dentro--><!--ancora dentro--><!----> | Pagina logica | 0 | 1 | 2 | 3 | | Frame | 5 | 7 | 1 | 2 | <!----> Quali sono le traduzioni dei seguenti indirizzi logici: 3, 4, 10, 32? <br /><br /><br /><br /> <!-- concur_macchina --> Si consideri la seguente soluzione al problema della mutua esclusione tra processi: <br /> <textarea cols="100" rows="10" readonly="readonly"> int bolt = 0; void P(int i) { while (bolt == 1) /* do nothing */; bolt = 1; /* critical section */; bolt = 0; /* remainder */; } </textarea> <br /> Assegnare un valore di verità alle seguenti affermazioni, spiegandone il motivo. * Assumendo che il dispatcher, prima o poi, dia l'opportunità di andare in esecuzione a tutti i processi coinvolti, è comunque possibile la starvation (rispetto all'entrata nella sezione critica) * Supponendo che ci siano 2 processi, se lo scheduler permette a =P(0)= di arrivare fino ad assegnare 1 a =bolt= senza interromperlo, allora il requisito base della mutua esclusione (sul numero massimo di processi nella sezione critica) è rispettato * Sono possibili deadlock <br /><br /><br /><br /> <!-- concur_semafori --> Si consideri la seguente soluzione al problema della mutua esclusione tra processi: <br /> <textarea cols="100" rows="10" readonly="readonly"> semaphore s = 0; void P(int i) { semWait(s); /* critical section */; semSignal(s); /* remainder */; } </textarea> <br /> Assegnare un valore di verità alle seguenti affermazioni, spiegandone il motivo. * Se si elimina la chiamata a =semWait=, il requisito base della mutua esclusione (sul numero massimo di processi nella sezione critica) è rispettato * È certo il deadlock * Il requisito base della mutua esclusione (sul numero massimo di processi nella sezione critica) è rispettato * Se si scambiano le chiamate =semWait= e =semSignal=, il requisito base della mutua esclusione (sul numero massimo di processi nella sezione critica) non è rispettato <br /><br /><br /><br /> <!-- concur_messaggi --> Si consideri la seguente soluzione al problema della mutua esclusione tra processi: <br /> <textarea cols="100" rows="17" readonly="readonly"> const message null = /* null message */; mailbox box; void P(int i) { message msg; while (true) { receive(box, msg); /* critical section */; send(box, msg); /* remainder */; } } void main() { box = create_mailbox(); nbsend(box, null); parbegin (P(1), P(2), . . ., P(n)); } </textarea> <br /> Assegnare un valore di verità alle seguenti affermazioni, spiegandone il motivo. * Se _n = 1_, non c'è deadlock * Il requisito base della mutua esclusione (sul numero massimo di processi nella sezione critica) è rispettato * Almeno un requisito della mutua esclusione non è rispettato * Se _n > 1_, non c'è deadlock <br /><br /><br /><br /> <!-- lettori_scrittori_semafori --> Si considerino le soluzioni al problema dei lettori/scrittori che usano i semafori viste a lezione, riportate qui di seguito:<br /> <img alt="" src="lezione24_slide71.png" /><br /> <img alt="" src="lezione24_slide72.png" /><br /> <img alt="" src="lezione24_slide73.png" /><br /> Assegnare un valore di verità alle seguenti affermazioni, spiegandone il motivo. * Nella soluzione che dà la precedenza agli scrittori, uno scrittore, in assenza di altri scrittori, nel momento in cui chiama =semWait(wsem)=, deve aspettare tutti e soli i lettori che attualmente hanno già eseguito =semWait(rsem)= * Usando la soluzione che dà la precedenza ai lettori, uno scrittore, in assenza di altri scrittori, nel momento in cui chiama =semWait(wsem)=, deve aspettare tutti e soli i lettori che attualmente stanno eseguendo =READUNIT= * Nella soluzione che dà la precedenza agli scrittori, uno scrittore, nel momento in cui chiama =semWait(wsem)=, deve aspettare tutti e soli i lettori che attualmente stanno eseguendo =READUNIT= <br /><br /><br /><br /> <!-- lettori_scrittori_messaggi --> Si consideri la soluzione tramite scambio messaggi al problema dei lettori/scrittori vista a lezione.<br /> <textarea cols="100" rows="48" readonly="readonly"> void reader(int i) { while (true) { nbsend (readrequest, null); receive (controller_pid, null); READUNIT (); nbsend (finished, null); } } void writer(int j) { while (true) { nbsend (writerequest, null); receive (controller_pid, null); WRITEUNIT (); nbsend (finished, null); } } void controller() { count = MAX_READERS; while (true) { if (count > 0) { if (!empty (finished)) { /* da reader! */ receive (finished, msg); count++; } else if (!empty (writerequest)) { receive (writerequest, msg); writer_id = msg.sender; count = count - MAX_READERS; } else if (!empty (readrequest)) { receive (readrequest, msg); count--; nbsend (msg.sender, "OK"); } } if (count == 0) { nbsend (writer_id, "OK"); receive (finished, msg); /* da writer! */ count = MAX_READERS; } while (count < 0) { receive (finished, msg); /* da reader! */ count++; } /* while (count < 0) */ } /* while (true) */ } /* controller */ </textarea> <br /> Assegnare un valore di verità alle seguenti affermazioni, spiegandone il motivo. * Questa soluzione dà precedenza ai lettori * Se =count > 0=, allora c'è un solo scrittore attivo (ovvero, che abbia completato l'esecuzione della =receive=) * Se =count < 0=, allora c'è un solo lettore attivo (ovvero, che abbia completato l'esecuzione della =receive=) * Si può sostituire il messaggio ="OK"= col messaggio nullo * C'è una corsa critica nel controllore: tra il test =empty= e la ricezione del messaggio, lo scheduler potrebbe interrompere il controllore stesso. Tuttavia, la soluzione è corretta <br /><br /><br /><br /> <!-- concur_messaggi --> Si consideri la soluzione al problema del produttore/consumatore che usa lo scambio messaggi vista a lezione. <br /> <textarea cols="100" rows="28" readonly="readonly"> const int capacity = /* buffering capacity */ ; mailbox mayproduce, mayconsume; void main() { mayproduce = create_mailbox(), mayconsume = create_mailbox(); for (int i = 1; i <= capacity; i++) nbsend (mayproduce,null); parbegin (producer,consumer); } void producer() { message pmsg; while (true) { receive (mayproduce,pmsg); pmsg = produce(); /* fa anche append */ nbsend (mayconsume,pmsg); } } void consumer() { message cmsg; while (true) { receive (mayconsume,cmsg); consume (cmsg); /* fa anche take */ nbsend (mayproduce,null); } } </textarea> <br /> Si supponga che venga usata così com'è per produttori e consumatori multipli. Assegnare un valore di verità alle seguenti affermazioni, spiegandone il motivo. * Assumendo che non ci siano errori in precedenza, è possibile che 2 produttori tentino di immettere contemporaneamente 2 diversi prodotti nello stesso slot del buffer * Assumendo che non ci siano errori in precedenza, è possibile che un consumatore tenti di prelevare un prodotto dal buffer quando quest'ultimo è vuoto * Assumendo che non ci siano errori in precedenza, è possibile che un produttore tenti di immettere un prodotto nel buffer quando quest'ultimo è pieno <br /><br /><br /><br /> <!-- grafi_allocazione_risorse --> Si supponga che la situazione ad un incrocio sia la seguente:<br /> <img alt="" src="deadlock.png" /><br /> Supponendo che la macchina 1 voglia girare a destra, mentre tutte le altre vogliano andare dritto, qual è il grafo delle allocazioni delle risorse corretto? E se tutte girano a destra? <br /><br /><br /><br /> <!-- trastevere --> Si consideri la soluzione al problema della strettoia di Trastevere vista a lezione.<br /> <textarea cols="100" rows="27" readonly="readonly"> semaphore z = 1; semaphore strettoia = 4; semaphore sx = 1; semaphore dx = 1; int nsx = 0; int ndx = 0; macchina_dal_lato_sinistro() { wait(z); wait(sx); ++nsx; if (nsx <span>= 1) wait(dx); signal(sx); signal(z); wait(strettoia); passa_strettoia(); signal(strettoia); wait(sx); --nsx; if(nsx =</span> 0) signal(dx); signal(sx); } </textarea> <br /> Si supponga che, ad un dato istante, ci siano 3 macchine da sinistra nella strettoia, 3 macchina da sinistra che stanno per eseguire =wait(strettoia)=, e 2 macchina da destra in attesa (su quali grafi?). Si supponga che ora arrivino altre 2 macchine da sinistra. Descrivere come evolverà la situazione, supponendo che non ci siano altri arrivi. <br /><br /><br /><br /> <a name="esercizi_8"/> ---++ Esercizi da 8 punti Per rispondere, __non__ è concesso consultare libro e dispense <br /><br /><br /><br /> <!-- semafori --> I seguenti tre processi concorrenti condividono due semafori<!--forti no, non importa-->: <br /> <textarea cols="100" rows="11" readonly="readonly"> semaphore U = 3; semaphore V = 0; [Process 1] [Process 2] [Process 3] while(1) { while(1) { while(1) { semWait(U); semWait(V); semWait(V); print("A"); print("B"); print("C"); semSignal(V); semSignal(V); } } } </textarea> <br /> Tenendo presente che l'unica assunzione possibile sul dispatcher è che, prima o poi, dia l'opportunità di andare in esecuzione a tutti i processi, e che nessun altro processo manipola i semafori U e V, qual è il __minimo__ ed il __massimo__ numero di caratteri "A", "B" e "C" che potrebbero venir stampati durante l'esecuzione dei tre processi? <br /><br /><br /><br /> <!-- semafori --> I seguenti due processi concorrenti condividono una variabile ed un semaforo: <br /> <textarea cols="100" rows="10" readonly="readonly"> semaphore S = 1; int X = N; [Process 1] [Process 2] int Y; int Z; semWait(S); semWait(S); Y = X*2; Z = X+1; X = Y; X = Z; semSignal(S); semSignal(S); </textarea> <br /> Tenendo presente che l'unica assunzione possibile sul dispatcher è che, prima o poi, dia l'opportunità di andare in esecuzione a tutti i processi, e che nessun altro processo manipola né S né X, quali sono i possibili valori di X dopo che entrambi i processi terminano l'esecuzione? Cosa cambia se si elimina una delle chiamate a =semSignal=? e se si elimina una delle chiamate a =semWait=? <br /><br /><br /><br /> <!-- paginazione --> Un sistema con gestione paginata semplice della memoria ha indirizzi di _B_ bit e pagine di dimensione _P_ kB. Se tutta la memoria è paginabile, qual è il numero massimo di elementi contenuti nella tabella delle pagine di un processo? E se invece _K_ kB sono riservati al kernel e non sono paginabili? Si supponga inoltre che la tabella delle pagine sia organizzata in 2 livelli, in modo tale che la _page directory_ (primo livello) sia indirizzata da _D_ bit. Quanti bit saranno usati per indirizzare il secondo livello? Quante entry ci saranno, al massimo, tra tutte le tabelle delle pagine (primo e secondo livello) di un processo? <br /><br /><br /><br /> <!-- tempo_di_accesso --> Si consideri una unità disco con una velocità di rotazione di _R_ rivoluzioni al minuto (rpm). La testina, per spostarsi da una traccia alla successiva, impiega _t_ ms. Ogni traccia del disco contiene _T_ KiB. Si assuma che una porzione di dimensione _P_ kB di un file sia memorizzata sul disco in settori contigui (si intendono contigui anche settori su diverse tracce, per i quali sia sufficiente il semplice spostamento della testina). Indicare qual è il tempo totale, in secondi, necessario per il trasferimento di questi _P_ <span> KiB di dati dal disco in memoria principale, nel caso in cui la testina sia già posizionata sul settore di partenza, che è il primo della traccia di cui fa parte. <br /><br /><br /><br /> </span> <!-- io_versus_cpu --> Un calcolatore multiprogrammato esegue _N_ processi concorrenti. Ciascun processo ha le medesime caratteristiche ed è strutturato in fasi di attività di lunghezza di _M_ millisecondi. Solo una frazione _0 < C ≤ 0.5_ di questi _M_ millisecondi è passata in attività di I/O, e tale attività è concentrata tutta alla fine di ciascuna fase. Il resto di ogni fase è quindi speso in attività di elaborazione sul processore. Ciascun processo viene eseguito per un totale complessivo di _F_ fasi di attività usando un semplice scheduler round-robin. Ciascun processore agisce su un dispositivo di I/O indipendente da quello su cui operano gli altri processi. Si ricavi la formula per il tempo medio di risposta, in ms, nel caso migliore e nel caso peggiore. Assumere trascurabile il tempo di switch tra processi. <br /><br /><br /><br /> <!-- io_versus_cpu --> Un calcolatore multiprogrammato esegue _N_ processi concorrenti. Ciascun processo ha le medesime caratteristiche ed è strutturato in fasi di attività di lunghezza di _M_ millisecondi. Solo una frazione _0 < C ≤ 0.5_ di questi _M_ millisecondi è passata in attività di I/O, e tale attività è concentrata tutta alla fine di ciascuna fase. Il resto di ogni fase è quindi speso in attività di elaborazione sul processore. Ciascun processo viene eseguito per un totale complessivo di _F_ fasi di attività usando un semplice scheduler round-robin. Ciascun processore agisce su un dispositivo di I/O indipendente da quello su cui operano gli altri processi. Si ricavi la formula per il throughput, in processi al ms, nel caso migliore e nel caso peggiore. Assumere trascurabile il tempo di switch tra processi. <br /><br /><br /><br /> <!-- scheduling_formule --> Considerare un insieme di _n_ processi <em>P<sub>1</sub>, ..., P<sub>n</sub></em>. Per ciascun processo, sono noti i tempi (_time-stamp_) di arrivo <em>A<sub>1</sub>, ..., A<sub>n</sub></em>, i tempi di servizio <em>S<sub>1</sub>, ..., S<sub>n</sub></em> ed i tempi (_time-stamp_) di terminazione <em>C<sub>1</sub>, ..., C<sub>n</sub></em>; questi ultimi vengono ottenuti tramite un qualche algoritmo di _scheduling_. Rispondere alle seguenti domande: * Come è definito il throughput? * Come è definito il valor medio del tempo di turnaround normalizzato? * Come è definito il tempo medio di turnaround? * Ci sono sufficienti informazioni per definire il tempo medio di attesa? <br /><br /><br /><br /> <!-- trad_ind_log --> Si consideri una memoria di _B_ byte suddivisa in _P_ pagine, dove _P_ divide _B_, ovvero _B = b*P_ con _b_ intero e potenza di 2 (<em>b = 2<sup>k</sup></em> per qualche _k_ intero). Quindi, le pagine sono da _b = B/P_ byte ciascuna. La page table di un processo in esecuzione è data dalla funzione _p : {1, ..., P} → {1, ..., P}_. Nel seguito, si indica con _y div z_ il quoziente intero tra _y_ e _z_, con _y mod z_ il resto della divisione intera tra _y_ e _z_, con _y << z_ lo shift a sinistra di _y_ per _z_ bit e con _y >> z_ lo shift a destra di _y_ per _z_ bit. Qual è la formula per tradurre un generico indirizzo logico _x_ in indirizzo fisico? Supporre dapprima di avere a disposizione le operazioni di divisione intera e di modulo, e poi di avere a disposizione solo operazioni di shift e il modulo. <br /><br /><br /><br /> <!-- lettori_scrittori_messaggi --> Si consideri la soluzione tramite scambio messaggi al problema dei lettori/scrittori vista a lezione.<br /> <textarea cols="100" rows="48" readonly="readonly"> void reader(int i) { while (true) { nbsend (readrequest, null); receive (controller_pid, null); READUNIT (); nbsend (finished, null); } } void writer(int j) { while (true) { nbsend (writerequest, null); receive (controller_pid, null); WRITEUNIT (); nbsend (finished, null); } } void controller() { int count = MAX_READERS; while (true) { if (count > 0) { if (!empty (finished)) { /* da reader! */ receive (finished, msg); count++; } else if (!empty (writerequest)) { receive (writerequest, msg); writer_id = msg.sender; count = count - MAX_READERS; } else if (!empty (readrequest)) { receive (readrequest, msg); count--; nbsend (msg.sender, "OK"); } } if (count == 0) { nbsend (writer_id, "OK"); receive (finished, msg); /* da writer! */ count = MAX_READERS; } while (count < 0) { receive (finished, msg); /* da reader! */ count++; } /* while (count < 0) */ } /* while (true) */ } /* controller */ </textarea> <br /> Correggere tale codice in modo tale che non ci sia più la limitazione sul numero massimo di lettori. A tal scopo, usare una variabile booleana aggiuntiva che viene settata quando uno scrittore vuole eseguire =READUNIT=. Aggiungere anche un opportuno =main=. <br /><br /><br /><br /> <!-- lettori_scrittori_messaggi --> Si consideri la soluzione tramite scambio messaggi al problema dei lettori/scrittori vista a lezione.<br /> <textarea cols="100" rows="48" readonly="readonly"> void reader(int i) { while (true) { nbsend (readrequest, null); receive (controller_pid, null); READUNIT (); nbsend (finished, null); } } void writer(int j) { while (true) { nbsend (writerequest, null); receive (controller_pid, null); WRITEUNIT (); nbsend (finished, null); } } void controller() { count = MAX_READERS; while (true) { if (count > 0) { if (!empty (finished)) { /* da reader! */ receive (finished, msg); count++; } else if (!empty (writerequest)) { receive (writerequest, msg); writer_id = msg.sender; count = count - MAX_READERS; } else if (!empty (readrequest)) { receive (readrequest, msg); count--; nbsend (msg.sender, "OK"); } } if (count == 0) { nbsend (writer_id, "OK"); receive (finished, msg); /* da writer! */ count = MAX_READERS; } while (count < 0) { receive (finished, msg); /* da reader! */ count++; } /* while (count < 0) */ } /* while (true) */ } /* controller */ </textarea> <br /> * Supporre che le mailbox non siano gestite con una FIFO, ma in modo non specificato, come avviene per i semafori deboli. Allora, può esserci starvation? Se sì, fornire un esempio; se no, motivare. * Si supponga di non avere il test =empty=. Come si sarebbe dovuto riscrivere il controllore? <br /><br /><br /><br /> <a name="esercizi_12"/> ---++ Esercizi da 12 punti Per rispondere, __non__ è concesso consultare libro e dispense <br /><br /><br /><br /> <!-- semafori --> I seguenti tre processi concorrenti stampano caratteri come indicato: <br /> <textarea cols="100" rows="6" readonly="readonly"> [Process 1] [Process 2] [Process 3] while(1) { while(1) { while(1) { print("A"); print("B"); print("C"); } } } </textarea> <br /> Si richiede di dichiarare e gestire opportunamente dei semafori in modo tale che i caratteri vengano stampati secondo la seguente tabella: <!--ancora dentro--> <!--ancora dentro--><!--ancora dentro--><!--ancora dentro--><!--ancora dentro--><!--ancora dentro--><!--ancora dentro--> <!--ancora dentro--><!--ancora dentro--><!--ancora dentro--><!--ancora dentro--><!--ancora dentro--><!--ancora dentro--> | | *A* | *B* | *C* | | *minimo* | infinito | 0 | 4 | | *massimo* | infinito | limitato | 4 | <!--ancora dentro--> È richiesto anche di gestire la stessa =print= come una risorsa critica cui accedere in mutua esclusione. <br /> Si assuma solo che il dispatcher, prima o poi, dia l'opportunità di andare in esecuzione a tutti i processi, e che nessun altro processo manipoli i semafori che verranno aggiunti. Non è consentito modificare o cancellare le istruzioni già presenti.<br /> <br /><br /><br /><br /> <!-- produttore_consumatore_mod_sem --> Un produttore P produce dati che mette in tre code FIFO, identificate con q0, q1 e q2, in modo circolare fra le tre. Tre consumatori C0, C1 e C2, prelevano un dato per volta, rispettivamente dalle code q0, q1 e q2, e li elaborano.<br /> I tempi di ogni singola produzione ed elaborazione sono molto irregolari, al punto che un consumatore può trovare la propria coda vuota, nel qual caso può prelevare un dato dalla coda successiva in senso circolare.<br /> Scrivere lo pseudo codice corrispondente ai processi P, C0, C1 e C2, utilizzando semafori generali per la sincronizzazione, e sapendo che le code q0, q1 e q2 sono di lunghezza uguale (e finita). <br /> <br /><br /><br /><br /> <!-- produttore_consumatore_mod_sem --> 3 produttori P0, P1 e P2 producono dati che mettono in 3 code FIFO, identificate con q0, q1 e q2, rispettivamente. Un consumatore C preleva un dato per volta, in modo circolare tra le code q0, q1 e q2, e lo elabora.<br /> I tempi di ogni singola produzione ed elaborazione sono molto irregolari, al punto che un produttore può trovare la propria coda piena, nel qual caso può prelevare un dato dalla coda successiva in senso circolare.<br /> Scrivere lo pseudo codice corrispondente ai processi P0, P1, P2 e C, utilizzando semafori generali per la sincronizzazione, e sapendo che le code q0, q1 e q2 sono di lunghezza uguale (e finita). <br /> <br /><br /><br /><br /> <!-- lock --> Si supponga di avere a disposizione, come metodo di sincronizzazione, solamente le primitive =lock/unlock=. Entrambe prendono in input un'etichetta e funzionano in modo simile alle =semWaitB/semSignalB= di un semaforo binario inizializzato ad 1, con la limitazione che una chiamata ad =unlock= non ha nessun effetto se prima non era stata chiamata la =lock=. Risolvere il problema del produttore/cnsumatore usando solo le dette primitive. <br /><br /><br /><br /> <!-- barrier --> Talvolta le applicazioni concorrenti sono divise in fasi con la regola che nessun processo può proseguire se prima tutti i suoi simili non sono pronti a farlo. Le barriere implementano questo concetto: un processo che ha terminato la sua fase chiama una primitiva =barrier= e si blocca. Quando tutti i processi coinvolti hanno terminato il loro stadio di esecuzione invocando anch'essi la primitiva =barrier=, il sistema li sblocca tutti permettendo di passare ad uno stadio successivo. Un'applicazione concorrente composta da _N_ processi utilizza più volte durante la sua esecuzione il meccanismo della =barrier=. Dovendo migrare l'applicazione in questione ad un sistema operativo che non fornisce tale meccanismo, ma che fornisce condivisione di memoria e semafori, si richiede di scrivere la primitiva =barrier= in termini dei meccanismi disponibili. <br /><br /><br /><br /> <!-- barrier_exch --> Talvolta le applicazioni concorrenti sono divise in fasi con la regola che nessun processo può proseguire se prima tutti i suoi simili non sono pronti a farlo. Le barriere implementano questo concetto: un processo che ha terminato la sua fase chiama una primitiva =barrier= e si blocca. Quando tutti i processi coinvolti hanno terminato il loro stadio di esecuzione invocando anch'essi la primitiva =barrier=, il sistema li sblocca tutti permettendo di passare ad uno stadio successivo. Un'applicazione concorrente composta da _N_ processi utilizza più volte durante la sua esecuzione il meccanismo della =barrier=. Dovendo migrare l'applicazione in questione ad un sistema operativo che non fornisce tale meccanismo, ma che fornisce solo l'istruzione atomica =exchange= (e ovviamente la memoria condivisa), si richiede di scrivere la primitiva =barrier= in termini dei meccanismi disponibili. <br /><br /><br /><br /> <!-- barrier_mess --> Talvolta le applicazioni concorrenti sono divise in fasi con la regola che nessun processo può proseguire se prima tutti i suoi simili non sono pronti a farlo. Le barriere implementano questo concetto: un processo che ha terminato la sua fase chiama una primitiva =barrier= e si blocca. Quando tutti i processi coinvolti hanno terminato il loro stadio di esecuzione invocando anch'essi la primitiva =barrier=, il sistema li sblocca tutti permettendo di passare ad uno stadio successivo. Un'applicazione concorrente composta da _N_ processi utilizza più volte durante la sua esecuzione il meccanismo della =barrier=. Dovendo migrare l'applicazione in questione ad un sistema operativo che non fornisce tale meccanismo, ma che fornisce solo lo scambio di messaggi, si richiede di scrivere la primitiva =barrier= in termini dei meccanismi disponibili. <br /><br /><br /><br />
E
dit
|
A
ttach
|
Watch
|
P
rint version
|
H
istory
: r1
|
B
acklinks
|
V
iew topic
|
Ra
w
edit
|
M
ore topic actions
Topic revision: r1 - 2018-12-12
-
IgorMelatti
Log In
or
Register
SO/SO1213AL Web
Create New Topic
Index
Search
Changes
Notifications
Statistics
Preferences
Prenotazioni esami
Laurea Triennale ...
Laurea Triennale
Algebra
Algoritmi
Introduzione agli algoritmi
Algoritmi 1
Algoritmi 2
Algoritmi per la
visualizzazione
Architetture
Prog. sist. digitali
Architetture 2
Basi di Dati
Basi di Dati 1 Inf.
Basi di Dati 1 T.I.
Basi di Dati (I modulo, A-L)
Basi di Dati (I modulo, M-Z)
Basi di Dati 2
Calcolo
Calcolo differenziale
Calcolo integrale
Calcolo delle Probabilitą
Metodi mat. per l'inf. (ex. Logica)
canale AD
canale PZ
Programmazione
Fond. di Programmazione
Metodologie di Programmazione
Prog. di sistemi multicore
Programmazione 2
AD
EO
PZ
Esercitazioni Prog. 2
Lab. Prog. AD
Lab. Prog. EO
Lab. Prog. 2
Prog. a Oggetti
Reti
Arch. di internet
Lab. di prog. di rete
Programmazione Web
Reti di elaboratori
Sistemi operativi
Sistemi Operativi (12 CFU)
Anni precedenti
Sistemi operativi 1
Sistemi operativi 2
Lab. SO 1
Lab. SO 2
Altri corsi
Automi, Calcolabilitą
e Complessitą
Apprendimento Automatico
Economia Aziendale
Elaborazione Immagini
Fisica 2
Grafica 3D
Informatica Giuridica
Laboratorio di Sistemi Interattivi
Linguaggi di Programmazione 3° anno Matematica
Linguaggi e Compilatori
Sistemi Informativi
Tecniche di Sicurezza dei Sistemi
ACSAI ...
ACSAI
Computer Architectures 1
Programming
Laurea Magistrale ...
Laurea Magistrale
Percorsi di studio
Corsi
Algoritmi Avanzati
Algoritmica
Algoritmi e Strutture Dati
Algoritmi per le reti
Architetture degli elaboratori 3
Architetture avanzate e parallele
Autonomous Networking
Big Data Computing
Business Intelligence
Calcolo Intensivo
Complessitą
Computer Systems and Programming
Concurrent Systems
Crittografia
Elaborazione del Linguaggio Naturale
Estrazione inf. dal web
Fisica 3
Gamification Lab
Information Systems
Ingegneria degli Algoritmi
Interazione Multi Modale
Metodi Formali per il Software
Methods in Computer Science Education: Analysis
Methods in Computer Science Education: Design
Prestazioni dei Sistemi di Rete
Prog. avanzata
Internet of Things
Sistemi Centrali
Reti Wireless
Sistemi Biometrici
Sistemi Distribuiti
Sistemi Informativi Geografici
Sistemi operativi 3
Tecniche di Sicurezza basate sui Linguaggi
Teoria della
Dimostrazione
Verifica del software
Visione artificiale
Attivitą complementari
Biologia Computazionale
Design and development of embedded systems for the Internet of Things
Lego Lab
Logic Programming
Pietre miliari della scienza
Prog. di processori multicore
Sistemi per l'interazione locale e remota
Laboratorio di Cyber-Security
Verifica e Validazione di Software Embedded
Altri Webs ...
Altri Webs
Dottorandi
Commissioni
Comm. Didattica
Comm. Didattica_r
Comm. Dottorato
Comm. Erasmus
Comm. Finanziamenti
Comm. Scientifica
Comm Scientifica_r
Corsi esterni
Sistemi Operativi (Matematica)
Perl e Bioperl
ECDL
Fondamenti 1
(NETTUNO)
Tecniche della Programmazione 1° modulo
(NETTUNO)
Seminars in Artificial Intelligence and Robotics: Natural Language Processing
Informatica generale
Primo canale
Secondo canale
II canale A.A. 10-11
Informatica
Informatica per Statistica
Laboratorio di Strumentazione Elettronica e Informatica
Progetti
Nemo
Quis
Remus
TWiki ...
TWiki
Tutto su TWiki
Users
Main
Sandbox
Home
Site map
AA web
AAP web
ACSAI web
AA2021 web
Programming web
AA2021 web
AN web
ASD web
Algebra web
AL web
AA1112 web
AA1213 web
AA1920 web
AA2021 web
MZ web
AA1112 web
AA1213 web
AA1112 web
AA1314 web
AA1415 web
AA1516 web
AA1617 web
AA1819 web
Old web
Algo_par_dis web
Algoreti web
More...
SO1213AL Web
Create New Topic
Index
Search
Changes
Notifications
RSS Feed
Statistics
Preferences
P
P
P
View
Raw View
Print version
Find backlinks
History
More topic actions
Edit
Raw edit
Attach file or image
Edit topic preference settings
Set new parent
More topic actions
Account
Log In
Register User
Questo sito usa cookies, usandolo ne accettate la presenza. (
CookiePolicy
)
Torna al
Dipartimento di Informatica
E
dit
A
ttach
Copyright © 2008-2025 by the contributing authors. All material on this collaboration platform is the property of the contributing authors.
Ideas, requests, problems regarding TWiki?
Send feedback