Difference between revisions of "Prove svolte e soluzioni proposte"

From Sistemi Operativi
Jump to navigation Jump to search
 
(170 intermediate revisions by 15 users not shown)
Line 1: Line 1:
Questa pagina serve a raccogliere prove d'esame svolte (che possono essere utili alla preparazione) e soluzioni proposte a tali prove da sottoporre a peer-review.
+
Questa pagina raccoglie prove d'esame svolte (che possono essere utili alla preparazione) e soluzioni proposte a tali prove da sottoporre a peer-review. Chiunque prenda visione di un esercizio è pregato (per il bene collettivo) a lasciare una [https://www.mediawiki.org/wiki/Help:Signatures propria firma] con nome utente e data di visualizzazione indicando se lo svolgimento è ritenuto corretto; in caso di svolgimento scorretto è invece invitato ad apportare una correzione o a '''spiegare il perché dell'errore commesso''', lasciando come nel caso precedente il proprio nome utente e data di correzione.
  
== Esame 19/09/2018 ==
+
Al fine di verificare la correttezza degli esercizi di concorrenza, segnaliamo la presenza di [[Tool_per_semafori_e_monitor|strumenti di programmazione concorrente]] per i linguaggi C e Python.
Soluzioni proposte da: Mattia Biondi (da controllare)
 
=== Esercizio c.1 (sbagliato) ===
 
<source lang="c">
 
// Condition: MAX
 
// Condition: ok2load
 
// Condition: ok2unload
 
// Condition: ok2move
 
  
int airport_codes = [BLQ, CDG, BRX, LGW, FCO, ...]
+
== Prove scritte ==
struct luggage {
+
* [[Prove scritte 2023]]
    int dstcode;
+
* [[Prove scritte 2022]]
    int owner;
+
* [[Prove scritte 2021]]
};
+
* [[Prove scritte 2020]]
luggage cart[MAX];
+
* [[Prove scritte 2019]]
int loaded = 0;
+
* [[Prove scritte 2018]]
 +
* [[Prove scritte 2017]]
 +
* [[Prove scritte 2015]]
 +
* [[Prove scritte 2014]]
 +
* [[Prove scritte 2013]]
 +
* [[Prove scritte 2011]]
 +
* [[Prove scritte 2005]]
  
Procedure entry: void cartat(int code)
+
== Prove pratiche ==
{
+
* [[Prove pratiche 2022]]
    if(code == 0)
+
* [[Prove pratiche 2019]]
    {
+
* [[Prove pratiche 2018]]
        ok2unload.wait();
+
* [[Prove pratiche 2017]]
        ok2load.signal();
+
* [[Prove pratiche 2016]]
    }
 
    else
 
    {
 
        ok2load.wait();
 
        ok2unload.signal();
 
    }
 
}
 
 
 
Procedure entry: void load(int dstcode, int owner)
 
{
 
    ok2move.wait();
 
    if(loaded < MAX)
 
    {
 
        luggage l;
 
        l.dstcode = dstcode;
 
        l.owner = owner;
 
        cart.push(l);
 
        loaded++;
 
    }
 
    else ok2move.signal();
 
}
 
 
 
Procedure entry: int unload(int dstcode)
 
{
 
    ok2move.wait();
 
    int i;
 
    for(i=0; i<loaded; i++)
 
    {
 
        if(cart[i].dstcode == dstcode)
 
        {
 
            int owner = cart[i].owner;
 
            cart[i].remove();
 
            loaded--;
 
            return owner;
 
        }
 
    }
 
    else ok2move.signal();
 
}
 
</source>
 
<br>
 
 
 
=== Esercizio c.1 ===
 
<source lang="c">
 
monitor dispatch
 
condition go_cart;
 
condition ok2station; //quando la stazione può caricare
 
current_station = None
 
//dizionario con chiave destinazione
 
luggages = {}
 
 
 
def countl(luggages):
 
    n=0
 
    for d in luggages:
 
        n += len(luggages[d]);
 
 
 
p.e. cartat(code):
 
    current_station = code //carrello arriva alla stazione
 
    if (code == BLQ || len(luggages[code]) > 0):
 
        ok2station[code].signal()
 
        go_cart.wait()
 
    current_station = None //il carrello sta viaggiando tra le stazioni
 
 
 
p.e. load(dst, owner):
 
    if (current_station != BLQ || countl(luggages) >= MAX):
 
        ok2station(BLQ).wait()
 
    luggages[dst].append(owner)
 
    if (countl(luggages) >= MAX)
 
        go_cart.signal()
 
   
 
p.e. unload(dst):
 
    if (current_station != dst || len(luggages[dst]) == 0)
 
    //lunghezza lista dei bagagli con questa destinazione
 
        ok2station(dst).wait()
 
    owner = luggages[dst].pop()
 
    if len(luggages[dst]) == 0)
 
        go_cart.signal()
 
    return owner
 
</source>
 
<br>
 
 
 
=== Esercizio c.2 ===
 
<source lang="c">
 
/* MP sincrono dato quello asincrono */
 
 
 
void ssend(obj msg, process q)
 
{
 
    asend(msg, q);
 
    ack = areceive(q);
 
}
 
 
 
obj sreceive(process p)
 
{
 
    obj msg = areceive(p);
 
    asend(ack, p);
 
    return msg;
 
}
 
</source>
 
<br>
 
Soluzione proposta:
 
<source lang="c">
 
stack s;
 
 
 
void ssend(obj msg, process q)
 
{
 
    asend(msg, q);
 
    ack = areceive(q);
 
}
 
 
 
obj sreceive(process p)
 
{
 
    obj msg;
 
    while(msg = areceive(p))
 
    {
 
        s.push(msg);
 
    }
 
    asend(ack, p);
 
    return s.pop();
 
}
 
</source>
 
<br>
 
 
 
=== Esercizio g.1 ===
 
<nowiki>
 
x = long_compute()/short_compute()
 
X = io()
 
 
 
  0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 3 3 3 3 3 3 3 3 3 3 4 4 4 4 4 4 4 4 4 4 5 5 5 5 5 5 5 5 5 5 6 6 6 6 6 6 6 6 6 6 7 7 7 7 7 7 7 7 7 7 8 8 8
 
  0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2
 
P1 |x|x|x|x|x|X|-|-|-|-|-|-|X|X|X|-|-|-|-|-|-|X|x|x|-|-|-|-|-|-|x|x|x|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|X|X|X|-|-|-|-|-|-|X|X|x|-|-|-|-|-|-|x|-|-|
 
P2        |-|-|x|x|x|-|-|-|-|-|-|x|x|-|-|-|-|-|-|-|X|X|X|-|-|-|-|-|-|X|X|x|-|-|-|-|-|-|x|x|x|-|-|-|-|-|-|x|-|-|-|-|-|-|-|-|X|X|X|-|-|-|-|-|-|X|X|x|-|-|-|x|-|-|
 
P3              |-|-|x|x|x|-|-|-|-|-|-|x|x|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|X|X|X|-|-|-|-|-|-|X|X|x|-|-|-|-|-|-|x|x|x|-|-|-|-|-|-|x|-|-|-|-|-|-|-|-|X|X|X|-|-|-|X|X|x|x|
 
</nowiki>
 
<br>
 
=== Esercizio g.2 ===
 
a) Può richiedere supporto hardware. Se implementato con contatori o stack questi devono essere aggiornati ad ogni riferimento alla memoria. L'intero sistema viene appesantito e rallentato.<br>
 
b) Il journaling si assicura che i dati sul filesystem siano consistenti, ma non aggiornati. Assicura la coerenza dei dati, ma non la perdita dei file se il filesystem si danneggia.<br>
 
c) Si dice che un programma A ha lo stesso potere espressivo di un programma B quando è possibile esprimere ogni programma scritto con B mediante A. Per implementare MP sincrono dato quello asincrono basta aggiungere una libreria. Per implementare MP asincrono dato quello sincrono bisogna aggiungere un processo server.<br>
 
d) In questi casi tutte le istruzioni vengono eseguite con la massima autorità, con problemi di sicurezza nel caso un utente estraneo prenda il controllo del sistema o rischio di commettere gravi errori semplicemente sbagliando a digitare un comando.
 
 
 
== Esame 17/07/2018 ==
 
=== Esercizio c.1 ===
 
<source lang="c">
 
/* Monitor Delirum: */
 
 
 
// Condition: Ok2Load;
 
// Condition: Ok2Pour[]; // Un elemento per Type
 
int availableBeer[]; // Un elemento per Type
 
Queue requests[]; // Un elemento per Type
 
Queue pendingRequests;
 
 
 
Procedure entry: void Pour(Type t, Quantity c)
 
{
 
    if (c > availableBeer[t]) // Richiesta maggiore della birra disponibile
 
    {
 
        c -= availableBeer[t];
 
        availableBeer[t] = 0;             
 
        requests[t].Enqueue(c);
 
        if (requests[t].Length == 1) // Risveglio un magazziniere solo se è la prima richiesta di questo tipo di birra
 
        {
 
            pendingRequests.Enqueue(t);
 
            Ok2Load().Signal();
 
        }
 
        Ok2Pour[t].Wait();
 
        requests[t].Dequeue(); // Quando ho ottenuto la birra che voglio, elimino la mia richiesta
 
    }
 
    availableBeer[t] -= c;
 
}
 
 
 
Procedure entry: Type isEmpty()
 
{
 
    if (pendingRequests.Length == 0)
 
    {
 
        Ok2Load.Wait();
 
    }
 
    return pendingRequests.Dequeue();
 
}
 
 
 
Procedure entry: Loaded(Type t, Capacity c)
 
{
 
    availableBeer[t] += c;
 
    while (requests[t].Length > 0 && availableBeer[t] > requests[t].head())
 
    {
 
        Ok2Pour[t].Signal();
 
    }
 
 
 
    if (requests[t].Length > 0) // serve per evitare che a causa di un magazziniere lento si accodino cosi tante richieste che mentre si sta caricando si svuota subito il fusto
 
    {
 
        pendingRequests.Enqueue(t);
 
        Ok2Load.Signal();
 
    }
 
}
 
</source>
 
<br>
 
 
 
== Esame 29/05/2017 ==
 
=== Esercizio c.1 ===
 
<source lang="c">
 
condition okpartita
 
condition ok2chiama
 
condition ok2punteggio
 
condition ok2run[2][MAX]
 
int numpronti
 
int punteggio[2]
 
boolean partita=false
 
boolean partitafinita=false
 
chiamati = []
 
contabandiera[2]
 
int winner
 
 
 
p.e. nuovapartita():
 
{
 
    punteggio[A] = punteggio[B] = 0;
 
    numpronti = 0;
 
    partita=true;
 
    okpartita.signal()
 
    chiamati = [];
 
}
 
p.e. chiama(l):
 
{
 
    if (numpronti<2*MAX)
 
    {
 
        ok2chiama.wait();
 
    }
 
    chiamati = l;
 
    contabandiera[A] = contabandiera[B] = 0
 
    winner = -1;
 
    for (s in n)
 
    {
 
        ok2run[A][s].signal();
 
        ok2run[B][s].signal()
 
    }
 
    ok2punteggio.wait();
 
    punteggio[winner++]
 
    if (max(punteggio) == 10)
 
    {
 
        partitafinita = true;
 
        for (s in A,B)
 
        {
 
            for (n in range(MAX))
 
            {
 
                ok2run[s][n].signal();
 
            }
 
        }
 
    }
 
    return punteggio;
 
}
 
p.e. pronto(s, n):
 
{
 
    if (partitafinita) return 1;
 
    if (!partita)
 
    {
 
        okpartita.wait();
 
    }
 
    numpronti++;
 
    if (numpronti>=2*MAX)
 
    {
 
        ok2chiama.signal();
 
    }
 
    if (!(n in chiamati))
 
    {
 
        ok2run[s][n].wait();
 
    }
 
    numpronti--;
 
    return 0 if partita else 1;
 
}
 
allabandiera(s, n):
 
{
 
    contabandiera[s]++;
 
    if (winner == -1 && contabandiera[s] == len(chiamati))
 
    {
 
        winner = s;
 
    }
 
    if (contabandiera[A] == len(chiamati) && contabandiera[B] == len(chiamati))
 
    {
 
        ok2punteggio.signal();
 
    }
 
}
 
</source>
 
<br>
 
 
 
== Esame 16/07/2014 ==
 
=== Esercizio c.1 ===
 
<source lang="c">
 
/* Monitor Bounded Buffer: (non richiesto dall'esercizio) */
 
queue q;
 
condition oktoread; // q.length() > 0
 
condition oktowrite; // q.length() < MAX
 
 
 
procedure entry type read():
 
    if (q.length() == 0) oktoread.wait(); // controllo
 
    retval = q.dequeue(); // cambio lo stato
 
    // abilito coloro che possono essere abilitati dal cambiamento di stato
 
    oktowrite.signal()
 
    return retval;
 
 
 
procedure entry void write(type elem):
 
    if (q.length() >= MAX) oktowrite.wait(); //controllo
 
    q.enqueue(elem); // cambio lo stato
 
    oktoread.signal(); // abilito chi può essere abilitato
 
 
 
/* NOTE:
 
* procedure entry ==> dichiarazione di funzioni (senza vedere l'implementazione
 
* dall'esterno)
 
*/
 
</source>
 
<br>
 
<source lang="c">
 
/* Min-Max Monitor Bounded Buffer: */
 
 
 
Queue Q;
 
 
 
// Condition: OKTOREAD: Q.Length > MIN
 
// Condition: OKTOWRITE: Q.Length < MAX
 
 
 
procedure entry: Type Read():
 
{
 
    if (Q.Length <= MIN) OKTOREAD.Wait(); // Controllo
 
    retval = Q.Dequeue(); // Cambio di stato
 
    OKTOWRITE.Signal(); // Abilito chi vuole scrivere
 
    return retval; // Qui sono sicuro perchè ne ho eliminato uno prima
 
}
 
 
 
procedure entry: void Write(Type elem):
 
{
 
    if (Q.Length >= MAX) OKTOWRITE.Wait() // Controllo
 
    Q.Enqueue(elem); // Cambio di stato
 
    if (Q.Length > MIN) OKTOREAD.Signal(); // Abilito chi vuole leggere
 
}
 
</source>
 
<br>
 
=== Esercizio c.2 ===
 
<source lang="c">
 
Semaphore mutex = 1;
 
 
 
struct Elem
 
{
 
    Semaphore s;
 
    int counter;
 
}
 
 
 
struct Elem V[]; // Vettore a dimensione variabile. I nuovi elementi sono initializzati a s = 0, counter = 0.
 
 
 
void RendezVouz(int n)
 
{
 
    mutex.P(); // Blocco, decremento di 1 (il processo si blocca se il semaforo vale 0)
 
    V[n].counter++;
 
    if (V[n].counter < n)
 
    {
 
        mutex.V(); // Rilascia, incrementa di 1
 
        V[n].s.P();
 
    }
 
    V[n].counter--;
 
    if (V[n].counter > 0)
 
        V[n].s.V();
 
    else
 
        mutex.V();     
 
}
 
</source>
 
<br>
 
 
 
=== Esercizio g.1 ===
 
<nowiki>
 
    0241302 ==> soluzione corretta
 
(0)2  2200
 
(1)3  1111
 
(2)4  4442
 
(3)0  0333
 
 
 
    2 3 4 0 1 2 3 4  0  1  2  3 ==> soluzione proposta, non corretta perchè non è la stringa più corta
 
2          1 1 1 1  0  0  0  0
 
3          3 2 2 2  2  1  1  1
 
4          4 4 3 3  3  3  2  2
 
0          0 0 0 4  4  4  4  3
 
</nowiki>
 

Latest revision as of 15:49, 17 May 2023

Questa pagina raccoglie prove d'esame svolte (che possono essere utili alla preparazione) e soluzioni proposte a tali prove da sottoporre a peer-review. Chiunque prenda visione di un esercizio è pregato (per il bene collettivo) a lasciare una propria firma con nome utente e data di visualizzazione indicando se lo svolgimento è ritenuto corretto; in caso di svolgimento scorretto è invece invitato ad apportare una correzione o a spiegare il perché dell'errore commesso, lasciando come nel caso precedente il proprio nome utente e data di correzione.

Al fine di verificare la correttezza degli esercizi di concorrenza, segnaliamo la presenza di strumenti di programmazione concorrente per i linguaggi C e Python.

Prove scritte

Prove pratiche