407 lines
7.4 KiB
Markdown
407 lines
7.4 KiB
Markdown
|
# Semafori
|
||
|
|
||
|
## Inizializzazione
|
||
|
|
||
|
```
|
||
|
semaphore mutex = 1;
|
||
|
semaphore ospiti, locali, pulizia; // iniz. a 0
|
||
|
int nOsp = 0;
|
||
|
int nLoc = 0;
|
||
|
int attesaOspiti = 0;
|
||
|
int attesaLocali = 0;
|
||
|
bool chiusura;
|
||
|
```
|
||
|
## Ospiti
|
||
|
|
||
|
```
|
||
|
public void entraOspite () {
|
||
|
P (mutex);
|
||
|
if (nOsp == NMAX || chiusura) {
|
||
|
V (mutex);
|
||
|
attesaOspiti++;
|
||
|
P (ospiti);
|
||
|
attesaOspiti--;
|
||
|
}
|
||
|
nOsp++;
|
||
|
if (nOsp < NMAX && !chiusura && attesaOspiti > 0) {
|
||
|
V (ospiti);
|
||
|
} else {
|
||
|
V (mutex);
|
||
|
}
|
||
|
}
|
||
|
```
|
||
|
```
|
||
|
public void esciOspite () {
|
||
|
P (mutex);
|
||
|
nOsp--;
|
||
|
if (attesaOspiti > 0 && !chiusura) {
|
||
|
V (ospiti);
|
||
|
} else if (attesaOspiti == 0 && attesaLocali > 0 && nOsp == 0 && !chiusura) {
|
||
|
V (locali);
|
||
|
} else if (nOsp == 0 && chiusura) {
|
||
|
V (pulizia);
|
||
|
} else {
|
||
|
V (mutex);
|
||
|
}
|
||
|
}
|
||
|
```
|
||
|
|
||
|
## Locali
|
||
|
|
||
|
```
|
||
|
public void entraLocale () {
|
||
|
P (mutex);
|
||
|
if (chiusura || nLoc == NMAX || (attesaOspiti > 0 && nLoc == 0)) {
|
||
|
V (mutex);
|
||
|
attesaLocali++;
|
||
|
P (locali);
|
||
|
attesaLocali--;
|
||
|
}
|
||
|
nLoc++;
|
||
|
if (nLoc < NMAX && !chiusura && attesaLocali > 0) {
|
||
|
V (locali);
|
||
|
} else {
|
||
|
V (mutex);
|
||
|
}
|
||
|
}
|
||
|
```
|
||
|
```
|
||
|
public void esciLocale () {
|
||
|
P (mutex);
|
||
|
nLoc--;
|
||
|
|
||
|
if (nLoc == 0 && !chiusura && attesaOspiti > 0) {
|
||
|
V (ospiti);
|
||
|
} else if (attesaLocali > 0 && !chiusura) {
|
||
|
V (locali);
|
||
|
} else if (nLoc == 0 && chiusura) {
|
||
|
V (pulizia);
|
||
|
} else {
|
||
|
V (mutex);
|
||
|
}
|
||
|
}
|
||
|
```
|
||
|
## Barista
|
||
|
|
||
|
```
|
||
|
public void pulisciBar () {
|
||
|
P (mutex);
|
||
|
chiusura = true;
|
||
|
if (nLoc > 0 || nOsp > 0) {
|
||
|
V (mutex);
|
||
|
P (pulizia);
|
||
|
}
|
||
|
<...pulisci...>
|
||
|
chiusura = false;
|
||
|
|
||
|
if (attesaOspiti > 0) {
|
||
|
V (ospiti);
|
||
|
} else if (attesaLocali > 0) {
|
||
|
V (locali);
|
||
|
} else {
|
||
|
V (mutex);
|
||
|
}
|
||
|
}
|
||
|
```
|
||
|
|
||
|
# Monitor
|
||
|
|
||
|
```
|
||
|
monitor bar {
|
||
|
int nLoc = 0;
|
||
|
int nOsp = 0;
|
||
|
bool chiusura = false;
|
||
|
condition locali, ospiti, pulizia;
|
||
|
|
||
|
public void entraOspite() {
|
||
|
if (nOsp == NMAX || chiusura) {
|
||
|
wait (ospiti);
|
||
|
}
|
||
|
nOsp++;
|
||
|
if (nOsp < NMAX && !chiusura && !empty(ospiti)) {
|
||
|
signal (ospiti);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
public void esciOspite () {
|
||
|
nOsp--;
|
||
|
|
||
|
if (!empty(ospiti) > 0 && !chiusura) {
|
||
|
signal (ospiti);
|
||
|
} else if (nOsp == 0 && empty(ospiti) == 0 && !empty (locali) > 0 && !chiusura) {
|
||
|
signal (locali);
|
||
|
} else if (nOsp == 0 && chiusura) {
|
||
|
signal (pulizia);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
public void entraLocale () {
|
||
|
if (nLoc == NMAX || chiusura || (!empty(attesaOspiti) && nLoc == 0)) {
|
||
|
wait (locali);
|
||
|
}
|
||
|
nLoc++;
|
||
|
if (nLoc < NMAX && !chiusura && !empty (locali)) {
|
||
|
signal (locali);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
public void esciLocale () {
|
||
|
nLoc--;
|
||
|
|
||
|
if (!empty (ospiti) && nLoc == 0 && !chiusura) {
|
||
|
signal (ospiti);
|
||
|
} else if (!empty (locali) && empty (ospiti) && !chiusura) {
|
||
|
signal (locali);
|
||
|
} else if (nLoc == 0 && chiusura) {
|
||
|
signal (pulizia);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
public void pulisciBar () {
|
||
|
chiusura = true;
|
||
|
if (nLoc > 0 || nOsp > 0) {
|
||
|
wait (pulizia);
|
||
|
}
|
||
|
<...pulisci...>
|
||
|
chiusura = false;
|
||
|
if (!empty(ospiti) {
|
||
|
signal (ospiti);
|
||
|
} else if (!empty (locali)) {
|
||
|
signal (locali);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
```
|
||
|
# Scambio di messaggi asincrono
|
||
|
|
||
|
Implementazione in scambio di messaggi **asincrono** del problema "il bar dello stadio".
|
||
|
Seguono le implementazioni del processo gestore e le interfacce Barista, Locali, Ospiti.
|
||
|
|
||
|
## Gestore
|
||
|
|
||
|
```
|
||
|
process gestoreBar {
|
||
|
port signal entraOsp, entraLoc, esciOsp, esciLoc;
|
||
|
port signal richiestaPulizia, finePulizia;
|
||
|
process barista, locale, ospite;
|
||
|
int nLoc = 0;
|
||
|
int nOsp = 0;
|
||
|
bool chiusura = false;
|
||
|
signal s;
|
||
|
queue attesaOsp, attesaLoc; // inizializzate come empty
|
||
|
|
||
|
// helper function per svegliare in maniera corretta i processi in coda
|
||
|
public void svegliaProcesso () {
|
||
|
|
||
|
if (chiusura && nOsp == 0 && nLoc == 0) {
|
||
|
send (s) to barista.ok_pulizia;
|
||
|
barista = receive (s) from finePulizia;
|
||
|
|
||
|
} else if (!chiusura && !attesaOsp.empty && nLoc == 0) {
|
||
|
while (!attesaOsp.empty && nOsp < NMAX) {
|
||
|
ospite = attesaOsp.dequeue();
|
||
|
send (s) to ospite.ok_entra;
|
||
|
nOsp++;
|
||
|
}
|
||
|
|
||
|
} else if (!chiusura && !attesaLoc.empty && nOsp == 0 && attesaOsp.empty) {
|
||
|
while (!attesaLoc.empty && nLoc < NMAX) {
|
||
|
locale = attesaLoc.dequeue();
|
||
|
send (s) to locale.ok_entra;
|
||
|
nLoc++;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
...
|
||
|
// implementazione con guardie logiche
|
||
|
do {
|
||
|
* (nLoc == 0 && !chiusura && nOsp < NMAX); ospite = receive(s) from entraOsp; ->
|
||
|
send(s) to ospite.ok_entra;
|
||
|
nOsp++;
|
||
|
|
||
|
* (nOsp == 0 && !chiusura && nLoc < NMAX); locale = receive(s) from entraLoc; ->
|
||
|
send(s) to ospite.ok_entra;
|
||
|
nLoc++;
|
||
|
|
||
|
* (chiusura || (nOsp == NMAX && nLoc == 0)); ospite = receive(s) from entraOsp; ->
|
||
|
attesaOsp.enqueue(ospite)
|
||
|
|
||
|
* (chiusura || (nLoc == NMAX && nOsp == 0)); locale = receive(s) from entraLoc; ->
|
||
|
attesaLoc.enqueue(locale)
|
||
|
|
||
|
* barista = receive(s) from richiestaPulizia; ->
|
||
|
chiusura = true;
|
||
|
if (nLoc == 0 && nOsp == 0) {
|
||
|
send (s) to barista.ok_pulizia;
|
||
|
// qui pulisce
|
||
|
barista = receive(s) from finePulizia;
|
||
|
chiusura = false;
|
||
|
|
||
|
svegliaProcesso();
|
||
|
}
|
||
|
|
||
|
* ospite = receive(s) from esciOsp; ->
|
||
|
nOsp--;
|
||
|
svegliaProcesso();
|
||
|
|
||
|
* locale = receive(s) from esciLoc; ->
|
||
|
nLoc--;
|
||
|
svegliaProcesso();
|
||
|
} od
|
||
|
```
|
||
|
|
||
|
## Barista
|
||
|
|
||
|
```
|
||
|
process Barista {
|
||
|
port signal ok_pulizia;
|
||
|
signal s;
|
||
|
process p;
|
||
|
...
|
||
|
send (s) to gestoreBar.richiestaPulizia;
|
||
|
p = receive(s) from ok_pulizia;
|
||
|
<...pulisci...>
|
||
|
send (s) to gestoreBar.finePulizia;
|
||
|
...
|
||
|
}
|
||
|
```
|
||
|
|
||
|
## Ospiti
|
||
|
|
||
|
```
|
||
|
process Ospite {
|
||
|
port signal ok_entra;
|
||
|
signal s;
|
||
|
process p;
|
||
|
...
|
||
|
send (s) to gestoreBar.entraOsp;
|
||
|
p = receive(s) from ok_entra;
|
||
|
<...bevi birra come un vero tifoso in trasferta...>
|
||
|
send (s) to gestoreBar.esciOsp;
|
||
|
...
|
||
|
}
|
||
|
```
|
||
|
|
||
|
## Locali
|
||
|
|
||
|
```
|
||
|
process Locale {
|
||
|
port signal ok_entra;
|
||
|
signal s;
|
||
|
process p;
|
||
|
...
|
||
|
send (s) to gestoreBar.entraLoc;
|
||
|
p = receive(s) from ok_entra;
|
||
|
<...bevi birra come un vero tifoso in casa...>
|
||
|
send (s) to gestoreBar.esciLoc;
|
||
|
...
|
||
|
}
|
||
|
```
|
||
|
# Rendez-vous
|
||
|
|
||
|
```
|
||
|
process bar {
|
||
|
entry entraOspite;
|
||
|
entry ok_entraOspite;
|
||
|
entry entraLocale;
|
||
|
entry ok_entraLocale;
|
||
|
entry esciOspite;
|
||
|
entry esciLocale;
|
||
|
entry pulizia;
|
||
|
entry ok_pulizia;
|
||
|
entry fine_pulizia;
|
||
|
int nLoc = 0;
|
||
|
int nOsp = 0;
|
||
|
int attesaLoc = 0;
|
||
|
int attesaOsp = 0;
|
||
|
bool chiusura = false;
|
||
|
|
||
|
do {
|
||
|
* (!chiusura); accept entraOspite {}; ->
|
||
|
if (nOsp == NMAX) {
|
||
|
attesaOsp++;
|
||
|
} else {
|
||
|
accept ok_entraOspite;
|
||
|
nOsp++;
|
||
|
}
|
||
|
|
||
|
* accept esciOspite {}; ->
|
||
|
nOsp--;
|
||
|
if (attesaOsp > 0 && !chiusura) {
|
||
|
while (attesaOsp > 0 && nOsp < NMAX) {
|
||
|
accept ok_entraOspite;
|
||
|
}
|
||
|
} else if (attesaOsp == 0 && !chiusura && nOsp == 0 && attesaLoc > 0) {
|
||
|
while (attesaLoc > 0 && nLoc < NMAX) {
|
||
|
accept ok_entraLocale;
|
||
|
}
|
||
|
} else if (chiusura && nOsp == 0) {
|
||
|
accept ok_pulizia;
|
||
|
}
|
||
|
|
||
|
* (!chiusura); accept entraLocale {}; ->
|
||
|
if (nLoc == NMAX || (attesaOsp > 0 && nLoc == 0)) {
|
||
|
attesaLoc++;
|
||
|
} else {
|
||
|
accept ok_entraLocale;
|
||
|
nLoc++;
|
||
|
}
|
||
|
|
||
|
* accept esciLocale {}; ->
|
||
|
nLoc--;
|
||
|
if (nLoc == 0 && attesaOsp > 0 && !chiusura) {
|
||
|
while (attesaOsp > 0 && nOsp < NMAX) {
|
||
|
accept ok_entraOspite;
|
||
|
}
|
||
|
} else if (attesaLoc > 0 && !chiusura) {
|
||
|
while (attesaLoc > 0 && nLoc < NMAX) {
|
||
|
accept ok_entraLocale;
|
||
|
}
|
||
|
} else if (chiusura && nLoc == 0) {
|
||
|
accept ok_pulizia;
|
||
|
}
|
||
|
|
||
|
* accept pulizia {}; ->
|
||
|
chiusura = true;
|
||
|
if (nLoc == 0 && nOsp == 0) {
|
||
|
accept ok_pulizia;
|
||
|
}
|
||
|
|
||
|
* accept fine_pulizia {}; ->
|
||
|
chiusura = false;
|
||
|
} od
|
||
|
}
|
||
|
```
|
||
|
## Ospiti
|
||
|
|
||
|
```
|
||
|
process ospite {
|
||
|
...
|
||
|
call bar.entraOspite;
|
||
|
call bar.ok_entraOspite;
|
||
|
... bevi ...
|
||
|
call bar.esciOspite;
|
||
|
}
|
||
|
```
|
||
|
## Locali
|
||
|
```
|
||
|
process locale {
|
||
|
...
|
||
|
call bar.entraLocale;
|
||
|
call bar.ok_entraLocale;
|
||
|
... bevi ...
|
||
|
call bar.esciLocale;
|
||
|
}
|
||
|
```
|
||
|
## Barista
|
||
|
```
|
||
|
process barista {
|
||
|
...
|
||
|
call bar.pulizia;
|
||
|
call bar.ok_pulizia;
|
||
|
... pulisci ...
|
||
|
call bar.fine_pulizia;
|
||
|
}
|
||
|
```
|