PROGRAMMAZIONE CONCORRENTE IN JAVA

Размер: px
Начинать показ со страницы:

Download "PROGRAMMAZIONE CONCORRENTE IN JAVA"

Транскрипт

1 PROGRAMMAZIONE CONCORRENTE IN JAVA Supporto per il monitor con condition esplicite Al fine di facilitare l uso del monitor di Hoare in Java, sono utili le seguenti classi e interfacce appartenenti al package sde.monitor. public interface Condition{ public void Wait(); public void Signal(); //Condition public interface ConditionP{ public void Wait( int priority ); public void Signal(); //ConditionP public final class Monitor{ private SemaforoBinario mutex=new SemaforoBinario(1); private SemaforoBinario urgent=new SemaforoBinario(0); private int urgentcount=0; public void Enter(){ mutex.p(); //Enter public void Exit(){ if( urgentcount > 0 ) urgent.v(); else mutex.v(); //Exit public Condition newcondition(){ return new ConditionVariable(); private class ConditionVariable implements Condition{ private SemaforoBinario xsem=new SemaforoBinario(0); private int xcount=0; public void Wait() { xcount++; if( urgentcount>0 ) urgent.v(); else mutex.v(); xsem.p(); xcount--; //Wait public void Signal() { if( xcount>0 ) { urgentcount++; xsem.v(); urgent.p(); urgentcount--; 40

2 //Signal //ConditionVariable public ConditionP newconditionp(){ return new ConditionVariablePriorited(); private class ConditionVariablePriorited implements ConditionP{ private SemaforoBinarioAPriorita xsem=new SemaforoBinarioAPriorita(0); private int xcount=0; public void Wait( int priority ) { xcount++; if( urgentcount>0 ) urgent.v(); else mutex.v(); xsem.p( priority ); xcount--; //Wait public void Signal() { if( xcount>0 ) { urgentcount++; xsem.v(); urgent.p(); urgentcount--; //Signal //ConditionVariablePriorited //Monitor La classe Monitor e l interfaccia Condition rendono automatica la dichiarazione di semafori e associati contatori, in tal modo semplificando al massimo le operazioni di programmazione. Una condition appartiene ad un monitor. La creazione di una condition si ottiene invocando il metodo newcondition() su un oggetto monitor. Di seguito si riassumono le convenzioni che il programmatore deve rispettare per un uso corretto dei monitor in Java. Un monitor si programma come una classe passiva che dichiara come variabili di istanza una variabile di tipo Monitor, es. mon, e tante variabili condition quante ne servono per il monitor. Ciascuna entry procedure va strutturata come segue: //procedure entry ep() public /*entry*/ void ep(){ mon.enter(); corpo di ep; mon.exit(); //ep; 41

3 Detta x una variabile condition, le relative operazioni wait e signal sono evocate semplicemente come x.wait() e x.signal() rispettivamente. Come si vede le formalità sono ridotte all osso ed il rischio di commettere errori, rispetto alle espansioni in linea, minimizzato. Per entry procedure funzionali, cioè che restituiscono esplicitamente un risultato, bisogna prestare attenzione che la mon.exit() va invocata prima dell istruzione return. Sul problema dei lettori-scrittori È stato già affrontato in precedenza mostrando una soluzione (basata sui semafori) che dà priorità ai lettori. Se la risorsa è libera, essa è attribuita ad uno scrittore od un lettore. Mentre un lettore è in accesso, eventuali altri lettori in arrivo guadagnano immediatamente l accesso alla risorsa. Mentre uno scrittore è in accesso, tutti gli altri processi devono aspettare. Uno scrittore in attesa è svegliato dall ultimo lettore che abbandona la risorsa o da uno scrittore che termini l accesso. Tale soluzione crea evidentemente il pericolo di starvation degli scrittori. Per comodità, si propone una classe LettoriScrittori che introduce il vincolo per un thread di chiedere l autorizzazione ad effettuare un operazione (es. iniziolettura etc.) e a segnalarne la conclusione (es. finelettura). public class LettoriScrittori { //Ammette la possibilita' di starvation degli scrittori SemaforoBinario mutex_scrittori=new SemaforoBinario( 1 ); SemaforoBinario mutex_lettori=new SemaforoBinario( 1 ); int contatore_lettori=0; public void iniziolettura(){ mutex_lettori.p(); contatore_lettori++; if( contatore_lettori == 1 ) mutex_scrittori.p(); mutex_lettori.v(); public void finelettura(){ mutex_lettori.p(); contatore_lettori--; if( contatore_lettori == 0 ) mutex_scrittori.v(); mutex_lettori.v(); public void inizioscrittura(){ mutex_scrittori.p(); public void finescrittura(){ mutex_scrittori.v(); //LettoriScrittori 42

4 Di seguito si presenta un altra soluzione, strutturata con monitor e condition esplicite, in grado di evitare la starvation. Essa è basata sulle seguenti assunzioni: iniziolettura() pone il lettore in wait se uno scrittore è in fase di accesso o se almeno uno scrittore è già in wait; diversamente consente l accesso al lettore e sveglia immediatamente altri lettori in attesa finelettura() abilita gli scrittori eventualmente in attesa inizioscrittura() pone il processo scrittore in wait se esistono lettori in attesa o un altro scrittore è già in fase di accesso finescrittura() sblocca la risorsa e sveglia eventuali processi lettori in attesa o, in alternativa, altri scrittori in attesa. Il monitor utilizza i seguenti dati: lettori (iniz 0), condition di attesa per i lettori scrittori (iniz 0), condition di attesa per gli scrittori lettoriinattesa (iniz 0), contatore dei lettori in wait su read-queue scrittoriinattesa (iniz 0), contatore degli scrittori in wait su write-queue scrittoreinaccesso (iniz false), booleano che indica se uno scrittore è già in fase di accesso lettoriinaccesso (iniz 0), contatore dei lettori in fase di accesso. //file LettoriScrittori.java package sde.lettoriscrittori; import sde.monitor.*; public class LettoriScrittori { private Monitor monitor=new Monitor(); private Condition lettori=monitor.newcondition(); private Condition scrittori= monitor.newcondition(); private int lettoriinattesa=0; private int scrittoriinattesa=0; private int lettoriinaccesso=0; private boolean scrittoreinaccesso=false; public void iniziolettura(){ monitor.enter(); if( scrittoreinaccesso scrittoriinattesa > 0 ){ lettoriinattesa++; lettori.wait(); lettoriinattesa--; lettoriinaccesso++; lettori.signal(); monitor.exit(); 43

5 public void finelettura(){ monitor.enter(); lettoriinaccesso--; if( lettoriinaccesso == 0 ) scrittori.signal(); monitor.exit(); public void inizioscrittura(){ monitor.enter(); if( lettoriinaccesso > 0 scrittoreinaccesso ){ scrittoriinattesa++; scrittori.wait(); scrittoriinattesa--; scrittoreinaccesso=true; monitor.exit(); public void finescrittura(){ monitor.enter(); scrittoreinaccesso=false; if( lettoriinattesa > 0 ) lettori.signal(); else scrittori.signal(); monitor.exit(); //LettoriScrittori 44

6 Sul problema dei cinque filosofi È stata a suo tempo discussa un implementazione basata su monitor che evita il deadlock. A questo proposito si ricorda che l idea è di far richiedere ad un filosofo che intenda mangiare entrambe le forchette con un azione indivisibile. Si osserva qui che tale soluzione, mentre evita il deadlock non impedisce la starvation di un filosofo. Infatti è possibile, ad esempio, che i filosofi 0 e 3 ottengano le forchette e mangino, che il filosofo 4 voglia mangiare, che il filosofo 0 deponga le forchette, che il filosofo 0 richieda nuovamente le forchette e le ottenga in quanto il filosofo 3 non ha ancora rilasciato le sue e cosi via. Di seguito si fornisce una soluzione che evita deadlock e starvation e utilizza i seguenti dati: un array fork di 5 elementi (uno per filosofo), che contiene di momento in momento il numero di forchette a disposizione di ciascun filosofo un array count di 5 elementi (uno per filosofo), che contiene il contatore delle volte che ciascun filosofo ha mangiato La starvation è evitata assegnando ad un filosofo le due forchette richieste solo nel caso che entrambi i filosofi vicini non abbiano mangiato meno volte. In altre parole, dal momento che un filosofo emette la richiesta delle forchette, esso sarà costretto ad attendere o perchè non sono disponibili entrambe le forchette, o perchè il filosofo ha mangiato sino ad ora più volte dei suoi vicini. Si presentano due versioni della soluzione organizzate in una classe Manager che controlla il comportamento dei filosofi. La prima versione utilizza direttamente i meccanismi propri di Java (wait() e notify()). La seconda, invece, si basa su monitor e condition espliciti. Le variabili locali sin e des denotano i due filosofi vicini a quello corrente who. Si presti attenzione alla costruzione di oggetti array attraverso un aggregato di inizializzazione (new è implicita in questi casi). // file Manager.java package sde.filosofi; public class Manager{ private byte fork[]={ 2, 2, 2, 2, 2 ; private int count[]={ 0, 0, 0, 0, 0 ; public synchronized void getfork( int who ) { int sin=(who+4)%5, des=(who+1)%5; //filosofi adiacenti a who while( fork[who]<2 ( (count[who]>count[sin]) (count[who]>count[des]) ) ) { if( fork[who]<2 ) System.out.println("Filosofo "+who+" attende forchette"); else System.out.println("Filosofo "+who+" attende per fairness"); 45

7 try { wait(); catch(interruptedexception e) { fork[sin]--; fork[des]--; ;//getfork public synchronized void putfork( byte who ) { System.out.println("Filosofo "+who+" rilascia forchette"); int sin=(who+4)%5, des=(who+1)%5; fork[sin]++; fork[des]++; count[who]++; notifyall(); ;//putfork //Manager La struttura di un generico filosofo è mostrata di seguito: public class Filosofo extends Thread { private byte io; private Manager m; public Filosofo( byte io, Manager m ){ this.io=io; this.m=m; public void run() { while(true){ System.out.println("Filosofo "+io+" pensa..."); try{ sleep( (int)(math.random()*5000 ) ); catch(interruptedexception e) {; m.getfork( io ); System.out.println("Filosofo "+io+" mangia..."); try{ sleep( (int)(math.random()*5000 ) ); catch(interruptedexception e) {; m.putfork( io ); //run //Filosofo Una possibile classe di test è la seguente: // file T5F.java import sde.filosofi.*; public class T5F{ public static void main(string args[]) { Manager m=new Manager(); Filosofo f[]=new Filosofo[5]; for(byte i=0;i<f.length;i++) { 46

8 f[i]=new Filosofo( i, m ); f[i].start(); //T5F Si presenta ora una differente implementazione della classe Manager fondata sui concetti di monitor e condition. Nessuna modifica è richiesta alle classi Filosofo e T5F. //file Manager.java package sde.filosofi; import sde.monitor.*; public class Manager{ private byte fork[]={ 2, 2, 2, 2, 2 ; private int count[]={ 0, 0, 0, 0, 0 ; private Monitor monitor=new Monitor(); private Condition Fil[]={ monitor.new Condition(), monitor.new Condition(), monitor.new Condition(), monitor.new Condition(), monitor.new Condition() ; public void getfork( int who ) { monitor.enter(); int sin=(who+4)%5, des=(who+1)%5; while( fork[who]<2 ((count[who]>count[sin]) (count[who]>count[des])) ) { if( fork[who]<2 ) System.out.println("Filosofo "+who+" attende forchette"); else System.out.println("Filosofo "+who+" attende per fairness"); Fil[who].Wait(); fork[sin]--; fork[des]--; monitor.exit(); ;//getfork public void putfork( byte who ) { monitor.enter(); System.out.println("Filosofo "+who+" rilascia forchette"); int sin=(who+4)%5, des=(who+1)%5; fork[sin]++; fork[des]++; count[who]++; 47

9 if( fork[sin]==2 ) Fil[sin].Signal(); if( fork[des]==2 ) Fil[des].Signal(); monitor.exit(); ;//putfork //Manager Nella nuova formulazione della classe Manager è stato introdotto un array Fil di condition, una condition per filosofo, ed una variabile Monitor. Allorquando un filosofo non ha entrambe le forchette o comunque deve attendere per ragioni di fairness, si pone in wait sulla sua condition. Gestione di buffer pool per grandi quantità di dati Si tratta di un estensione del problema produttore-consumatore-buffer al caso in cui ogni elemento di dato da trasferire dal produttore al consumatore è di grosse proporzioni. Per migliorare l efficienza dell applicazione, si cerca di evitare che il dato venga prima generato su un area dati locale del produttore, quindi copiato dal produttore sul buffer, quindi dal buffer ad un area dati locale del consumatore per consentirne il consumo. A questo proposito si utilizza un pool di buffer liberi. Il produttore genera un dato riempiendo un buffer libero del pool. Quindi trasmette al consumatore l indirizzo o indice del pool in cui c è il dato. Lo schema è utilizzabile tra più coppie <prod,cons> collegate ciascuna da un diverso buffer circolare, i cui elementi sono indici del pool di buffer liberi condiviso tra tutte le coppie. Q1 P1 C1 Q2 P2 C2... Qi Pi Ci Pool di buffer liberi Il comportamento di un generico produttore/consumatore è schematizzato in pseudo codice di seguito: produttore: while(true) { 48

10 acquisisce un buffer dal pool e annota il suo indirizzo riempie il buffer aggiunge l indirizzo del buffer nella coda condivisa col consumatore consumatore: while(true) { rimuove dalla coda condivisa col produttore l indirizzo di un buffer svuota il buffer del pool rende libero l indirizzo del buffer utilizzato Ovviamente, operazioni di sincronizzazione e mutua esclusione vanno adottate sia tra produttore e consumatore nei riguardi della coda condivisa Qi, che nei confronti del pool di buffer liberi condiviso tra tutte le coppie. Si può programmare una classe monitor Gestore di una generica Qi, con operazioni get e put. Il monitor va quindi instanziato per ogni coppia <prod,cons>. Tale classe Gestore è identica alla classe BoundedBuffer vista in precedenza. Un altro monitor, Allocatore di risorse, con operazioni Acquisisci e Rilascia, va programmato per la gestione del pool. Un produttore potrebbe essere costretto ad attendere se un buffer libero non esiste nel pool. In realtà, il monitor Allocatore potrebbe mantenere dentro di sè un array Pool di indirizzi alle risorse (buffer) fisiche esistenti all esterno del monitor. Tale array andrebbe inizializzato con gli indirizzi dei vari buffer liberi esterni. In termini Java si ha: import sde.monitor.*; public class Allocatore { int[] Pool; int size, testa; Monitor monitor=new Monitor(); Condition bufferlibero=monitor.newcondition(); public Allocator( int[] addr ){ Pool=new int[addr.length]; size=addr.length; for(int i=0; i<pool.length; i++) Pool[i]=addr[i]; testa=size-1; //Allocatore 49

11 public int Acquisisci() { monitor.enter(); if(testa==-1) bufferlibero.wait(); int buffloc=pool[testa ]; monitor.exit(); return buffloc; //Acquisisci public void Rilascia( int buffloc ) { monitor.enter(); Pool[++testa]=buffloc; bufferlibero.signal(); monitor.exit(); ;//Rilascia //Allocatore Come si vede, Pool è gestito semplicemente a stack. Schedulatore del movimento della testina di un disco Il disco di un sistema di calcolo è una delle unita di I/O più importanti. Dall efficienza degli accessi al disco dipendono le prestazioni dell intero sistema. In quanto segue si discute un algoritmo di scheduling del movimento della testina capace di ottimizzare le prestazioni evitando starvation delle richieste. Il tempo di accesso al disco consiste in generale di tre contributi: tempo di seek (o di posizionamento) tempo di latenza (o di rotazione) tempo di trasferimento Il tempo di posizionamento è quello richiesto per spostare il braccio mobile con la testina di lettura/scrittura sulla traccia interessata dall operazione di accesso (si ricorda che un indirizzo su disco consiste di <numero di traccia, numero di settore nella traccia>. Dopo questo tempo, occorre attendere il ritardo di latenza per far giungere il settore sotto la testina. Statisticamente questo tempo può essere assunto pari alla metà del tempo di rotazione del disco. Segue infine il tempo di trasferimento che dipende evidentemente dall ammontare dell informazione in gioco. Dei tre tempi, quello iniziale di posizionamento è fondamentale ed è oggetto di controllo con un assegnato algoritmo di scheduling dei movimenti della testina. In un caso possibile, la testina potrebbe essere spostata, rispetto alla posizione corrente, sulla traccia più vicina in base alle richieste pendenti di accesso. 50

12 Quest algoritmo comporterebbe il rischio di ritardare indefinitamente alcune richieste. In alternativa, si potrebbe far muovere la testina da un bordo all altro del disco, attuando le richieste pendenti corrispondenti alle varie posizioni raggiunte, quindi invertendo il senso di spostamento ed esaudendo le altre richieste (algoritmo SCAN), o ripartendo di nuovo dall estremo iniziale (algoritmo C-SCAN). Un altra possibilità sarebbe quella di far muovere la testina non da un estremo all altro sistematicamente, ma limitando gli spostamenti alle ultime tracce, in ogni senso di marcia, oggetto di richiesta (gli algoritmi sono denominati rispettivamente LOOK e C-LOOK). In quanto segue si prende in considerazione un algoritmo di scheduling tipo LOOK: si fa muovere la testina nei due sensi di moto e durante ogni senso si eseguono le richieste. Si introduce un monitor DiskManager che esporta due procedure entry richiesta(traccia-dest:int) rilascio(), da chiamare a completamento di una operazione di I/O su disco. Un processo che richieda un accesso al disco dovrebbe seguire il protocollo: controllore-disco.richiesta( numero traccia ); legge o scrive sul disco alla traccia richiesta controllore-disco.rilascio; Il monitor in ogni momento può essere occupato a servire una richiesta. In questo caso una nuova richiesta va posta in wait. Il particolare senso di marcia in corso, se in (da traccia 1 a max traccia) o out, costituisce una variabile di stato. Inoltre servono due variabili condition, diciamole motoin e motoout su cui accodare appropriatamente le richieste, con annessi contatori count-motoin e count-motoout. Cura particolare va posta sulla gestione delle richieste che sopraggiungono dinamicamente e che si riferiscono alla posizione corrente della testina. Accettando di servirle subito, si potrebbe generare starvation di altre richieste. È opportuno quindi porre in wait queste richieste in modo da poterle obbedire al prossimo cambio di senso di moto. È evidente l interesse di schedulare le richieste in modo tale da riprenderle in base alla minima vicinanza alla posizione corrente. A questo scopo si suppone di utilizzare uno schema di monitor con condition con wait a priorità. La traccia destinazione di una richiesta può essere utilizzata come priorità: più piccolo è il suo valore, maggiore è la priorità. Nel senso di moto in, è ovvio che la successione delle richieste pendenti sulla condition motoin è utile che sia per traccia crescente. Su 51

13 motoout, invece, è opportuno far trovare per prime le richieste di traccia più grande. Dunque come priorità è utilizzabile, in questo caso, la differenza max_traccia - traccia richiesta. Segue una formulazione della classe DiskManager. //file DiskManager.java package sde.diskmanager; import sde.monitor.*; public class DiskManager { private final int max_traccia; private final int in=0, out=1; private int direzione=in; private boolean occupato=false; private int posizione=1; private Monitor m=new Monitor(); private ConditionP motoin=m.newconditionp(); private ConditionP motoout= m.newconditionp(); private int count_motoin=0, count_motoout=0; public DiskManager( int max_traccia ){ this.max_traccia=max_traccia; public void richiesta( int numero_traccia ){ m.enter(); if( occupato ){ if( posizione < numero_traccia posizione == numero_traccia && direzione == out ){ count_motoin++; motoin.wait( numero_traccia ); count_motoin--; else { count_motoout++; motoout.wait( max_traccia - numero_traccia ); count_motoout--; else{ //fissa senso di moto if( posizione <= numero_traccia ) direzione=in; else direzione=out; occupato=true; posizione=numero_traccia; m.exit(); //richiesta public void rilascio(){ m.enter(); occupato=false; if( direzione==in) if( count_motoin==0 ){ direzione=out; motoout.signal(); 52

14 else motoin.signal(); else if( count_motoout==0 ){ direzione=in; motoin.signal(); else motoout.signal(); m.exit(); //rilascio //DiskManager Si nota che il metodo richiesta schedula richieste per la traccia corrente sulla condition associata con il senso di moto opposto a quello corrente. Ad ogni modo, procedendo in un certo senso di marcia si processano tutte le richieste comunque presenti per il senso di moto. Richieste per una stessa traccia sono processate in ordine di arrivo FCFS. Il metodo richiesta, se invocato mentre occupato=false, provvede a fissare il senso di moto. La classe DiskManager richiede la disponibilità di monitor con condition a priorità (ConditionP). L implementazione di questo tipo di condition (si riveda la classe Monitor fornita in precedenza) dipende dalla classe semaforo binario a priorità richiamata di seguito. //file SemaforoBinarioAPriorita.java package sde.semaforo; import java.util.*; class Tripla{ Thread id; int priority; boolean sveglia; Tripla( Thread id, int priority, boolean sveglia ){ this.id=id; this.priority=priority; this.sveglia=sveglia; public class SemaforoBinarioAPriorita{ private Vector codaapriorita=new Vector(); private int contatore; public SemaforoBinarioAPriorita( int contatore ) throws BadInitializationException { if( contatore<0 contatore>1 ) throw new BadInitializationException(); this.contatore=contatore; public synchronized void P( int priority ){ 53

15 if( contatore==0 ){ if( codaapriorita.size()>0 && ((Tripla)codaAPriorita.get(0)).sveglia && priority < ((Tripla)codaAPriorita.get(0)).priority ){ //preemption sotto una V in corso int i; for( i=0; i<codaapriorita.size(); i++ ) if(!((tripla)codaapriorita.get(i)).sveglia ) break; ((Tripla)codaAPriorita.get(i-1)).sveglia=false; else { //inserisci in ordine questo thread su codaapriorita int pos=0; while( pos<codaapriorita.size() && ((Tripla)codaAPriorita.get(pos)).priority<=priority ) pos++; codaapriorita.add( pos, new Tripla( Thread.currentThread(), priority, false) ); while( true ){ try{ wait(); catch( InterruptedException e ){; Tripla t=(tripla)codaapriorita.get(0); if( Thread.currentThread()==t.id && t.sveglia ) { codaapriorita.remove(0); if( codaapriorita.size()>0 && ((Tripla)codaAPriorita.get(0)).sveglia ) notifyall(); break; contatore=0; public synchronized void V(){ if( codaapriorita.size()==0 ) contatore=1; else{ int i; for( i=0; i<codaapriorita.size(); i++ ) if(!((tripla)codaapriorita.get(i)).sveglia ) break; if( i<codaapriorita.size() ) ((Tripla)codaAPriorita.get(i)).sveglia=true; notifyall(); //SemaforoBinarioAPriorita La classe SemaforoBinarioAPriorita mantiene una lista codaapriorita in cui un thread che esegua P(p) e si sospenda dà luogo ad un nodo che occupa un posto fissato dalla priorità p. Ovviamente dal punto di vista Java l ordine di attesa è 54

16 diverso. Al tempo di una V si sveglia il thread in testa alla coda ponendo il campo sveglia del relativo nodo a true. Tutti gli altri thread in attesa hanno il campo sveglia a false. E possibile una situazione di preemption che si verifica allorquando, al tempo di una P, il thread richiedente trova il semaforo rosso e dovrebbe entrare in attesa. Tuttavia il nuovo thread ha priorità massima ed il thread in testa a codaapriorita è stato flaggato come da risvegliare. In queste condizioni, il thread in testa alla lista viene costretto a riaddormentarsi mentre il thread a massima priorità entra in sezione critica. Gli altri dettagli dovrebbero essere auto-esplicativi. L interfaccia ConditionP è identica a Condition salvo che ora utilizza SemaforoBinarioAPriorita. Nessuna modifica è richiesta a Monitor.java. 55

17 Casi di studio Buffer limitato generico Si ripresenta per comodità una soluzione al problema del buffer limitato che accetta come elementi valori di tipo Object. Per generalità si propone una classe astratta BufferLimitato e si forniscono tre implementazioni rispettivamente basate sui semafori (BufferLimitatoS), il monitor di Hoare (BufferLimitatoMH) ed il monitor nativo di Java (BufferLimitatoJS). Tutte le classi sono parte del package sde.buffer. Anche il programma di prova TB.java è inserito nello stesso package. Una classe astratta e generica BufferLimitato (Java 1.5) //file BufferLimitato.java package sde.buffer; public abstract class BufferLimitato<T>{ protected int n; protected T [] buffer; protected int in=0, out=0, count=0; public BufferLimitato( int n ){ this.n=n; buffer=(t[])new Object[n]; public abstract T get(); public abstract void put( T value ); //BufferLimitato Una classe BufferLimitatoS basata sui semafori //file BufferLimitatoS.java package sde.buffer; import sde.semaforo.*; public class BufferLimitatoS<T> extends BufferLimitato<T>{ protected SemaforoBinario mutex=new SemaforoBinario(1); protected SemaforoContatore empty; protected SemaforoContatore full; public BufferLimitatoS( int n ){ super(n); empty=new SemaforoContatore(n); full=new SemaforoContatore(0); 56

18 public T get(){ full.p(); mutex.p(); T ans=buffer[out]; out=(out+1)%n; count--; mutex.v(); empty.v(); return ans; //get public void put( T value ) { empty.p(); mutex.p(); buffer[in]=value; in=(in+1)%n; count++; mutex.v(); full.v(); //put //BufferLimitatoS Una classe BufferLimitatoMH basata sul monitor di Hoare //file BufferLimitatoMH.java package sde.buffer; import sde.monitor.*; public class BufferLimitatoMH<T> extends BufferLimitato<T> { protected Monitor m=new Monitor(); protected Condition nonempty=m.newcondition(); protected Condition nonfull=m.newcondition(); public BufferLimitatoMH( int n ){ super(n); public T get() { m.enter(); if( count==0 ) nonempty.wait(); T ans=buffer[out]; out=(out+1)%n; count--; nonfull.signal(); m.exit(); return ans; //get public void put( T value ) { m.enter(); if( count==n ) nonfull.wait(); buffer[in]=value; in=(in+1)%n; count++; nonempty.signal(); m.exit(); //put //BufferLimitatoMH 57

19 Una classe BufferLimitatoJS basata sul monitor nativo di Java //file BufferLimitatoJS.java package sde.buffer; public class BufferLimitatoJS<T> extends BufferLimitato<T> { public BufferLimitatoJS( int n ){ super(n); public synchronized T get() { while( count==0 ) try { wait(); catch (InterruptedException ignored) { T ans=buffer[out]; out=(out+1)%n; count--; notifyall(); return ans; //get public synchronized void put( T value ) { while( count==n ) try { wait(); catch (InterruptedException ignored) { buffer[in]=value; in=(in+1)%n; count++; notifyall(); //put //BufferLimitatoJS Un programma di prova TB.java //file TB.java package sde.buffer; class Producer extends Thread{ int id; int seed; BufferLimitato<Integer> bl; public Producer( int id, int seed, BufferLimitato<Integer> bl ){ this.id=id; this.seed=seed; this.bl=bl; public void run(){ while( true ){ System.out.println("Producer#"+id+" produces item# "+seed); bl.put( new Integer( seed ) ); //oppure: bl.put( seed ); //autoboxing dei tipi di base seed++; try{ sleep( (int)(math.random()*500 ) ); catch( InterruptedException e ){ //Producer 58

20 class Consumer extends Thread{ int id; BufferLimitato<Integer> bl; public Consumer( int id, BufferLimitato<Integer> bl ){ this.id=id; this.bl=bl; public void run(){ while( true ){ int x=((integer)bl.get()).intvalue(); //oppure: int x=bl.get(); //auto-unboxing System.out.println("Consumer#"+id+" got item# "+x); //Consumer public class TB{ public static void main( String []args ){ BufferLimitato<Integer> b=new BufferLimitatoMH<Integer>( 5 ); Producer p1=new Producer( 1, 0, b ); Producer p2=new Producer( 2, , b ); Consumer c1=new Consumer( 1, b ); Consumer c2=new Consumer( 2, b ); Consumer c3=new Consumer( 3, b ); p1.start(); p2.start(); c1.start(); c2.start(); c3.start(); //TB TB.java è parte del package sde.buffer. Tutto ciò semplifica l accesso alle classi BufferLimitatoS, BufferLimitatoMH, BufferLimitatoJS. Tuttavia per l esecuzione occorre avvertire l interprete di Java che il main è in una classe dello stesso package come segue: >java sde.buffer.tb INVIO ossia specificando per esplicito il package di appartenenza di TB.class. La soluzione proposta rende possibile cambiare l implementazione del buffer modificando nel metodo main l indicazione (al lato destro di BufferLimitato b=new BufferLimitatoXX( 5 )) della classe utilizzata. Nessun altra modifica è richiesta. Barbiere Addormentato Si deve gestire un salone in cui è presente un solo barbiere, una sedia di servizio ed un certo numero di sedie per l attesa dei clienti. Quando non ci sono clienti da servire, il barbiere si addormenta sulla sedia di servizio. Un cliente che arrivi e trovi il barbiere addormentato, lo sveglia e passa immediatamente in servizio. Un cliente che trovi il barbiere in servizio e qualche posto libero, aspetta il suo turno. Se non esistono posti a sedere, il cliente va via non servito. 59

21 Si mostrano tre soluzioni utilizzando rispettivamente i meccanismi Java standard (SaloneJS), il monitor di Hoare (SaloneMH) e i semafori binari (SaloneSB). Le realizzazioni sono parte del package sde.salone. La classe astratta Salone definisce le entità comuni alle varie implementazioni. Ogni estensione di Salone deve implementare il metodo run() dell interfaccia Runnable dal momento che il thread barbiere è incorporato all interno del salone. L operazione richiesta() è l unica che può essere utilizzata dai clienti. Essa ritorna false se al momento del tentativo il salone è tutto occupato, true se il cliente va via servito. //Salone.java package sde.salone; public abstract class Salone implements Runnable{ protected int sedie, posti; protected Thread barbiere=null; protected boolean dorme, //true se il barbiere dorme cliente; //true se un cliente e' seduto per servizio public Salone( int sedie ){ this.sedie=sedie; posti=sedie; dorme=true; cliente=false; barbiere=new Thread(this); public abstract boolean richiesta(); public abstract void run(); //Salone Una prima estensione di Salone si basa sull uso dei metodi synchronized e delle operazioni wait(), notify(), notifyall() di Java. //SaloneJS.java package sde.salone; public class SaloneJS extends Salone{ protected boolean fineattesa=false; public SaloneJS( int sedie ){ super( sedie ); barbiere.start(); 60

22 public synchronized boolean richiesta(){ if( posti==0 ) return false; if( posti<sedie!dorme ){ posti--; while( true ){ try{ wait(); catch(interruptedexception e){ if( fineattesa ){ fineattesa=false; cliente=true; //cliente si accomoda su poltrona barbiere notifyall(); break; else{ dorme=false; cliente=true; notify(); //cliente aspetta fine servizio while( cliente ) try{ wait(); catch(interruptedexception e){ return true; public void run(){ while( true ){ synchronized(this){ if(!cliente ){ if( posti==sedie ){ dorme=true; //barbiere dorme per assenza di clienti while( dorme ) try{ wait(); catch(interruptedexception e){ else{ posti++; fineattesa=true; notify(); //barbiere attende cliente per servizio while(!cliente ) try{ wait(); catch(interruptedexception e){ //servizio try{ Thread.sleep( (int)(math.random()*1000) ); catch(interruptedexception e){ synchronized(this){ cliente=false; //cliente si alza per fine servizio notifyall(); //while //run //SaloneJS 61

23 Si dovrebbe prestare attenzione al modo con cui si risvegliano i clienti dall attesa in sala di aspetto. Esiste la booleana fineattesa che viene posta a true dal barbiere. Il primo cliente che si sveglia (non necessariamente in ordine FIFO) trova la variabile a true, la mette a false e sveglia tutti i rimanenti thread (barbiere incluso). Gli altri clienti tornano a dormire, il barbiere si sveglia dall attesa che il cliente si sia accomodato per servizio. Un altro punto degno di nota è l attesa del cliente sotto servizio. Non potendosi distinguere tra questo thread cliente e gli eventuali altri cliente in attesa, l unica maniera che ha il barbiere per segnalare la fine del servizio è eseguire notifyall() avendo posto cliente=false e mantenendo fineattesa=false. Dunque a svegliarsi sarà solo il thread servito (d altra parte il barbiere è più che mai sveglio in questo momento). Gli altri dettagli dovrebbero essere auto-esplicativi. La seconda soluzione, SaloneMH, è equivalente a Salone JS ed utilizza monitor e condition esplicite. //SaloneMH.java package sde.salone; import sde.monitor.*; public class SaloneMH extends Salone{ private Monitor m=new Monitor(); private Condition attesa=m.newcondition(); private Condition barber=m.new Condition(); private Condition servizio=m.new Condition(); public SaloneMH( int sedie ){ super(sedie); barbiere.start(); public boolean richiesta(){ m.enter(); if( posti==0 ){ m.exit(); return false; if( posti<sedie!dorme ){ posti--; attesa.wait(); cliente=true; //cliente si accomoda su poltrona barbiere else{ dorme=false; cliente=true; barber.signal(); //cliente aspetta fine servizio servizio.wait(); m.exit(); return true; public void run(){ while( true ){ m.enter(); if(!cliente ){ if( posti==sedie ){ 62

24 dorme=true; barber.wait(); else{ posti++; attesa.signal(); m.exit(); //servizio try{ Thread.sleep( (int)(math.random()*1000) ); catch(interruptedexception e){ m.enter(); cliente=false; servizio.signal(); //fine servizio, cliente si alza m.exit(); //while //run //SaloneMH Si lascia allo studio del lettore la comprensione di tutti i dettagli di SaloneMH nonché una valutazione comparativa delle due soluzioni. Si presenta, infine, un implementazione della classe Salone, SaloneSB, basata sui semafori binari. Essa segue naturalmente dalla soluzione a monitor e condition esplicite. //SaloneSB.java package sde.salone; import sde.semaforo.*; public class SaloneSB extends Salone implements Runnable{ SemaforoBinario mutex=new SemaforoBinario(1); SemaforoBinario attesa=new SemaforoBinario(0); SemaforoBinario barber=new SemaforoBinario(0); SemaforoBinario inizioservizio=new SemaforoBinario(0); SemaforoBinario fineservizio=new SemaforoBinario(0); public SaloneSB( int sedie ){ super(sedie); barbiere.start(); public boolean richiesta(){ mutex.p(); if( posti==0 ){ mutex.v(); return false; if( posti<sedie!dorme ){ posti--; mutex.v(); attesa.p(); cliente=true; //cliente si accomoda su poltrona barbiere 63

25 mutex.v(); else{ dorme=false; cliente=true; barber.v(); inizioservizio.v(); fineservizio.p();//cliente aspetta fine servizio return true; public void run(){ while( true ){ mutex.p(); if(!cliente ){ if( posti==sedie ){ dorme=true; mutex.v(); barber.p(); mutex.v(); else{ posti++; attesa.v(); else mutex.v(); inizioservizio.p(); //servizio try{ Thread.sleep( (int)(math.random()*1000) ); catch(interruptedexception e){ mutex.p(); cliente=false; fineservizio.v(); //fine servizio, cliente si alza mutex.v(); //while //run //SaloneSB L utilizzo di una qualsiasi realizzazione di Salone necessita della caratterizzazione del cliente (o persona). Quella che segue è una classe appartenente allo stesso package sde.salone. //Persona.java package sde.salone; public class Persona extends Thread{ private Salone s; private int id; public Persona( Salone s, int id ) { this.s=s; this.id=id; public void run(){ if(!s.richiesta() ) System.out.println("Cliente "+"#"+id+" va via non servito"); else System.out.println("Cliente "+"#"+id+" va via servito"); 64

26 //Persona Come si vede, per generalità, Persona riceve un Salone. Dunque, senza alcuna modifica essa funziona trasparentemente con tutte e tre le implementazioni di Salone. I clienti arrivano al salone attraverso la porta implementata direttamente nel metodo main di un applicazione. Ciò che serve è un semplice meccanismo di generazione. //TSAL.java import sde.salone.*; public class TSAL{ public static void main(string []args){ Salone s=new SaloneXX( 5 ); int i=0; for(;;){ try{ Thread.sleep( (int)(math.random()*500) ); catch(interruptedexception e){ Persona c=new Persona(s,i); i++; c.start(); //TSAL La modifica da attuare per utilizzare l una o l altra implementazione del salone riguarda solo l uso del costruttore della classe a destra dell assegnazione: Salone s=new SaloneXX( 5 ); //XX può essere JS, MH e SB Canali sincroni CSP Si presentano due implementazioni del concetto di canale sincrono à la CSP. //file Channel.java package sde.csp; public abstract class Channel{ protected boolean senderok=false, receiverok=false; protected Object message; protected boolean senderconnected=false, receiverconnected=false; public abstract OutPort senderconnection(); public abstract InPort receiverconnection(); //Channel //file InPort.java package sde.csp; 65

27 public interface InPort{ public Object receive(); //InPort //file OutPort.java package sde.csp; public interface OutPort{ public void send( Object msg ); //OutPort A) Implementazione Java standard //file ChannelJS.java package sde.csp; public class ChannelJS extends Channel{ private InputPort ip=new InputPort(); private OutputPort op=new OutputPort(); private class InputPort implements InPort{ public Object receive(){ synchronized( ChannelJS.this ){ if(!senderconnected!receiverconnected ) throw new RuntimeException(); Object msg; receiverok=true; while(!senderok ) try{ ChannelJS.this.wait(); catch(interruptedexception e){ msg=message; senderok=false; receiverok=false; ChannelJS.this.notify(); return msg; //receive //InputPort private class OutputPort implements OutPort{ public void send( Object msg ){ synchronized( ChannelJS.this ){ if(!senderconnected!receiverconnected ) throw new RuntimeException(); message=msg; senderok=true; if( receiverok ) ChannelJS.this.notify(); while( senderok ) try{ ChannelJS.this.wait(); catch(interruptedexception e){ 66

28 //OutputPort public synchronized OutPort senderconnection(){ if( senderconnected ) throw new RuntimeException( Sender already connected ); senderconnected=true; return op; public synchronized InPort receiverconnection(){ if( receiverconnected ) throw new RuntimeException( Receiver already connected! ); receiverconnected=true; return ip; //ChannelJS La soluzione proposta si caratterizza per il tentativo di esportare interfacce diverse al sender ed al receiver impegnati su uno stesso canale. Il sender deve poter eseguire solo send. Il receiver solo receive. Per ottenere questo risultato, sono state introdotte due interfacce InPort ed OutPort e due inner class di Channel InputPort e OutputPort che implementano l omonima interfaccia. Di ciascuna inner class viene creato un singolo oggetto al tempo di costruzione del canale. E richiesto che sender e receiver si connettano preliminarmente all oggetto canale con la relativa intenzione. L operazione di connessione ritorna l interfaccia d uso del canale, ossia la visione come porta di uscita (per il sender) e porta di ingresso (per il receiver). A questo punto, ogni processo è vincolato dal protocollo stabilito dall interfaccia ottenuta. Per la corretta sincronizzazione del sender e receiver, si utilizza, nei metodi send/receive, il blocco sincronizzato in cui l oggetto provvisto di monitor è il canale. Tutto ciò si ottiene con la sintassi synchronized( ChannelJS.this ){... che chiarisce che this non si riferisce all oggetto della inner class ma all oggetto canale che lo ospita. Avrebbe poco senso utilizzare, essendo distinte le inner class InputPort e OutputPort, il pronome this (perchè?). Si osserva infine che l implementazione del rendezvous lascia l ultima parola al receiver. Ossia, è il receiver, che appena ottiene il messaggio, sblocca il sender ed entrambi riprendono ad eseguire in concorrenza. B) Implementazione mediante monitor di Hoare //file ChannelMH.java 67

29 package sde.csp; import sde.monitor.*; public class ChannelMH extends Channel{ private Monitor m=new Monitor(); private Condition csender=m.newcondition(); private Condition creceiver=m.newcondition(); private OutputPort op=new OutputPort(); private InputPort ip=new InputPort(); private class OutputPort implements OutPort{ public void send( Object msg ){ m.enter(); if(!receiverconnected ){ m.exit(); throw new RuntimeException( Receiver not connected ); message=msg; senderok=true; if(!receiverok ) csender.wait(); else creceiver.signal(); m.exit(); //OutputPort private class InputPort implements InPort{ public Object receive(){ m.enter(); if(!senderconnected ){ m.exit(); throw new RuntimeException( Sender not connected ); Object msg; receiverok=true; if(!senderok ){ creceiver.wait(); msg=message; senderok=false; receiverok=false; else{ msg=message; senderok=false; receiverok=false; csender.signal(); m.exit(); return msg; //InPort public OutPort senderconnection(){ m.enter(); if( senderconnected ){ m.exit(); throw new RuntimeException( Sender already connected! ); 68

30 senderconnected=true; m.exit(); return op; public InPort receiverconnection(){ m.enter(); if( receiverconnected ){ m.exit(); throw new RuntimeException( Receiver already connected! ); receiverconnected=true; m.exit(); return ip; //ChannelMH Un applicazione: Crivello di Eratostene parallelo Si mostra un programma che utilizza il concetto di canale sincrono nella ricerca dei numeri primi tra 2 ed un intero positivo assegnato N col metodo del crivello di Eratostene. L applicazione si basa su un thread generatore che provvede a generare in sequenza gli interi da 2 ad N, e su una pipeline di thread filtri, che di momento in momento riflette l insieme dei numeri primi conosciuti. Ogni filtro è depositario di un numero primo. Il suo compito è filtrare gli interi ricevuti in input. Un numero multiplo del proprio primo è sicuramente non primo e si può abbandonare (non trasmettere oltre nella pipeline). Un intero non multiplo del proprio primo va comunicato al prossimo filtro a valle. Se un tale filtro non esiste, allora si è in presenza di un nuovo primo. Si genera un nuovo filtro, lo si lega al primo individuato e si connette il filtro come ultimo stadio della pipeline. I collegamenti tra il generatore ed il primo filtro (associato al numero 2) e tra i diversi filtri della pipeline sono realizzati mediante canali sincroni. Pertanto, ad es., il generatore non provvede a produrre un nuovo intero se non ha consegnato (rendezvous) il precedente al primo filtro etc. A fine elaborazione, il generatore invia il tappo 0 al primo filtro. Il numero zero serve a richiedere in ordine ai filtri di emettere in uscita il proprio numero. Gli altri dettagli dovrebbero essere auto-esplicativi. //file Crivello.java package sde.csp; import sde.inout.*; class Generatore extends Thread{ int n; OutPort outport; public Generatore( int n ){ 69

31 this.n=n; Channel c=new ChannelJS(); outport=c.senderconnection(); Filtro f=new Filtro( 2, c.receiverconnection() ); public void run(){ for( int i=3; i<=n; i++ ){ outport.send( new Integer( i ) ); try{ sleep( (int)(math.random()*10) ); catch(interruptedexception e){ outport.send( new Integer(0) ); //Generatore class Filtro extends Thread{ static int conta=0; int primo; InPort inport; OutPort outport=null; public Filtro( int primo, InPort inport ){ this.primo=primo; this.inport=inport; start(); public void run(){ while( true ){ int x=((integer)inport.receive()).intvalue(); if( x==0 ){ Format.print( System.out, "%6d", primo ); conta++; if( conta%12==0 ) System.out.println(); if( outport!=null ) outport.send( new Integer( x ) ); break; if( x%primo!= 0 ){ if( outport==null ){ Channel c=new ChannelJS(); outport=c.senderconnection(); Filtro f=new Filtro( x, c.receiverconnection() ); else outport.send( new Integer( x ) ); //Filtro public class Crivello{ public static void main( String []args ){ System.out.println("Crivello di Eratostene Parallelo"); System.out.println("Trova i numeri primi tra 2 e N"); int n=console.readint("n="); Generatore g=new Generatore( n ); 70

32 g.start(); //Crivello Esercizi 1. (MergeSort parallelo) Si ha un vettore v di interi da ordinare col metodo MergeSort. Si divide v in due parti uguali e si attiva ricorsivamenteparallelamente un differente thread per ordinare ciascuna parte separatamente. Ad ogni thread, diciamolo Sorter, si passa v e due indici che individuano la porzione da ordinare. Finito l ordinamento delle due parti, il thread padre fa il merge delle due porzioni ordinate e termina a sua volta. Realizzare l attesa di un thread genitore dei due thread figli con l'operazione join. 2. (LettoriScrittori) Si progetti utilizzando il monitor nativo di Java la classe LettoriScrittori in modo da mantenere priorità ai lettori e assenza di starvation per gli scrittori. 3. (Ponte a senso unico alternato) Lungo una strada a due corsie e doppio senso di marcia, che procede in direzione nord-sud, vi è un ponte ad una sola corsia, percorribile a senso unico alternato. Il ponte ha la capacità di n automobili. Le automobili dirette verso nord (oppure verso sud) possono attraversare il ponte solo se non è attraversato da nessuna automobile diretta verso sud (oppure verso nord). Programmare in Java i processi automobile diretta verso nord e automobile diretta verso sud utilizzando prima il meccanismo dei semafori e poi una struttura a monitor. 4. (Il Problema dei fumatori di sigarette) Esistono tre fumatori ed un tabaccaio. Ciascun fumatore prepara continuamente una sigaretta e la fuma, ma per preparare e fumare la sigaretta il fumatore deve ovviamente disporre dei tre ingredienti fondamentali: carta, tabacco e fiammiferi. Un fumatore ha la carta, l altro il tabacco ed il terzo i fiammiferi. Il tabaccaio dispone dei tre ingredienti in quantità infinita. Il tabaccaio posa sul tavolo due ingredienti per volta. Il fumatore che dispone del terzo ingrediente mancante può preparare una sigaretta e fumarla, segnalando al tabaccaio quando ha terminato. Il tabaccaio, allora, mette altri due ingredienti sul tavolo e la storia si ripete. Si scriva un programma concorrente Java per sincronizzare tabaccaio e fumatori. 5. Si ha un sistema con n processi P1, P2,..., Pn, ciascuno dei quali è dotato di un numero di priorità unico. Si scriva un monitor che allochi a questi tre processi tre stampanti identiche, utilizzando i numeri di priorità per stabilire l ordine di allocazione. 71

33 6. Un file deve essere condiviso tra diversi processi, ciascuno dei quali ha un numero identificativo unico (pid). Al file possono accedere contemporaneamente più processi ma col vincolo che la somma di tutti i pid dei processi che accedono concorrentemente al file deve essere minore o uguale di una soglia S. Si scriva un programma basato sui monitor di Java per coordinare l accesso al file. La soluzione deve garantire che l ordine dei risvegli sia rigorosamente FIFO. 7. (Rendezvous) Si progetti una classe ChannelSB erede della classe Channel di cui al caso di studio sui canali sincroni, basata sull utilizzo dei semafori binari. Come test della nuova classe, si utilizzi il crivello di Eratostene. 8. L incrocio tra una strada di grande traffico e una strada pedonale è regolato da un semaforo. Il semaforo è normalmente verde per i veicoli che procedono nei due sensi lungo la strada di grande comunicazione. I pedoni che intendono attraversare possono ottenere il colore verde solo premendo un apposito pulsante. Programmare la gestione del semaforo in modo tale che entrambi, i veicoli e i pedoni, prima di procedere devono attendere una risposta esplicita dal gestore del semaforo. La politica del gestore è quella di accogliere le richieste dei pedoni solo quando non ha richieste pendenti da parte dei veicoli. 9. Una linea ferroviaria disposta in direzione nord-sud collega n stazioni, che la suddividono in n-1 tronchi, ed è percorsa da t treni. Le stazioni hanno indici 1..n, crescenti in senso nord-sud; il tronco compreso tra le stazioni i e i+1 ha indice i. Tutti i tronchi sono a binario unico. Per il transito o la sosta dei treni, la stazione i dispone di Bsudi binari riservati ai treni che viaggiano verso sud e Bnordi binari riservati ai treni che viaggiano verso nord. I treni sono processi permanenti che percorrono alternativamente la linea ferroviaria in direzione sud e nord; la stazione e il verso iniziale sono definiti tempo della loro creazione. Le risorse utilizzate dai treni sono i tronchi della ferrovia e i binari delle stazioni. Ad ogni treno è associata una priorità e le risorse sono assegnate in base alla priorità dei treni. Scrivere un programma che risolva il problema e valutare la possibilità di deadlock. 10. (Il problema dei tre barbieri) Costituisce una estensione del problema del barbiere addormentato presentato come caso di studio. In questa nuova situazione, si hanno tre barbieri e tre sedie di servizio, un sofà con 4 posti a sedere, un area presso la quale possono sostare al massimo 16 persone in piedi, una cassa presso cui un cliente servito paga prima di andarsene. Quando entra un cliente, si danno le seguenti possibilità: 72

34 se tutti i posti del sofà sono occupati cosi come la zona di attesa in piedi (20 persone sono già in attesa) il cliente se ne va se i barbieri sono occupati ed esistono posti disponibili sul sofà o, in mancanza, in piedi, il cliente attende se qualche barbiere sta dormendo, il primo cliente che entra lo sveglia per essere servito Prima di andare via, un cliente deve pagare alla cassa. Tuttavia, non esiste un cassiere. Un barbiere, non appena termina un servizio, può assumere temporaneamente le funzioni di cassiere e smaltire i clienti in coda per il pagamento. Quindi ritorna a servire clienti. Il sofà, l area di attesa in piedi e la lista dei clienti davanti alla cassa sono gestiti in forma FIFO. Non appena termina un servizio, il cliente che da più tempo aspetta sul sofà guadagna la sedia di un barbiere. Il posto libero sul sofà viene quindi occupato dal cliente che aspetta da più tempo nella zona in piedi etc. Progettare una soluzione del problema utilizzando separatamente il monitor di Java, il monitor di Hoare, i semafori. Occorre garantire l assenza di situazioni spiacevoli come: clienti che si affollano intorno alle sedie dei barbieri ostacolandone l attività; un cliente che siede su una poltrona di servizio sulle gambe di un cliente ancora in servizio; etc. 73

Monitor. Introduzione. Struttura di un TDA Monitor

Monitor. Introduzione. Struttura di un TDA Monitor Monitor Domenico Cotroneo Dipartimento di Informatica e Sistemistica Introduzione E stato introdotto per facilitare la programmazione strutturata di problemi in cui è necessario controllare l assegnazione

Подробнее

Realizzazione di Politiche di Gestione delle Risorse: i Semafori Privati

Realizzazione di Politiche di Gestione delle Risorse: i Semafori Privati Realizzazione di Politiche di Gestione delle Risorse: i Semafori Privati Condizione di sincronizzazione Qualora si voglia realizzare una determinata politica di gestione delle risorse,la decisione se ad

Подробнее

Il costrutto monitor [Hoare 74]

Il costrutto monitor [Hoare 74] Il monitor 1 Il costrutto monitor [Hoare 74] Definizione: Costrutto sintattico che associa un insieme di operazioni (entry, o public) ad una struttura dati comune a più processi, tale che: Le operazioni

Подробнее

Java Virtual Machine

Java Virtual Machine Java Virtual Machine programmi sorgente: files.java compilatore files.class bytecode linker/loader bytecode bytecode Java API files.class interprete macchina ospite Indipendenza di java dalla macchina

Подробнее

Java threads (2) Programmazione Concorrente

Java threads (2) Programmazione Concorrente Java threads (2) emanuele lattanzi isti information science and technology institute 1/28 Programmazione Concorrente Utilizzo corretto dei thread in Java emanuele lattanzi isti information science and

Подробнее

Tipi primitivi. Ad esempio, il codice seguente dichiara una variabile di tipo intero, le assegna il valore 5 e stampa a schermo il suo contenuto:

Tipi primitivi. Ad esempio, il codice seguente dichiara una variabile di tipo intero, le assegna il valore 5 e stampa a schermo il suo contenuto: Tipi primitivi Il linguaggio Java offre alcuni tipi di dato primitivi Una variabile di tipo primitivo può essere utilizzata direttamente. Non è un riferimento e non ha senso tentare di istanziarla mediante

Подробнее

Ottava Esercitazione. introduzione ai thread java mutua esclusione

Ottava Esercitazione. introduzione ai thread java mutua esclusione Ottava Esercitazione introduzione ai thread java mutua esclusione Agenda Esempio 1 Concorrenza in Java: creazione ed attivazione di thread concorrenti. Esercizio 2 da svolgere Concorrenza in Java: sincronizzazione

Подробнее

Il costrutto monitor [Hoare 74]

Il costrutto monitor [Hoare 74] Il monitor 1 Il costrutto monitor [Hoare 74] Definizione: Costrutto sintattico che associa un insieme di operazioni (entry o public) ad una struttura dati comune a più processi, tale che: Le operazioni

Подробнее

Esercizi sul Monitor in Java

Esercizi sul Monitor in Java Esercizi sul Monitor in Java 1 I filosofi a cena (E. Dijkstra, 1965) 5 filosofi sono seduti attorno a un tavolo circolare; ogni filosofo ha un piatto di spaghetti tanto scivolosi che necessitano di 2 forchette

Подробнее

Sistemi Operativi. Lez. 13: primitive per la concorrenza monitor e messaggi

Sistemi Operativi. Lez. 13: primitive per la concorrenza monitor e messaggi Sistemi Operativi Lez. 13: primitive per la concorrenza monitor e messaggi Osservazioni I semafori sono strumenti particolarmente potenti poiché consentono di risolvere ogni problema di sincronizzazione

Подробнее

Esercitazioni 7 e 8. Bounded Buffer con sincronizzazione Java (1)

Esercitazioni 7 e 8. Bounded Buffer con sincronizzazione Java (1) Università degli Studi della Calabria Corso di Laurea in Ingegneria Informatica A.A. 2001/2002 Corsi A e B Esercitazioni 7 e 8 Bounded Buffer con sincronizzazione Java (1) public class BoundedBuffer private

Подробнее

Pronto Esecuzione Attesa Terminazione

Pronto Esecuzione Attesa Terminazione Definizione Con il termine processo si indica una sequenza di azioni che il processore esegue Il programma invece, è una sequenza di azioni che il processore dovrà eseguire Il processo è quindi un programma

Подробнее

Soluzione dell esercizio del 2 Febbraio 2004

Soluzione dell esercizio del 2 Febbraio 2004 Soluzione dell esercizio del 2 Febbraio 2004 1. Casi d uso I casi d uso sono riportati in Figura 1. Figura 1: Diagramma dei casi d uso. E evidenziato un sotto caso di uso. 2. Modello concettuale Osserviamo

Подробнее

SAPIENZA Università di Roma Facoltà di Ingegneria dell Informazione, Informatica e Statistica

SAPIENZA Università di Roma Facoltà di Ingegneria dell Informazione, Informatica e Statistica SAPIENZA Università di Roma Facoltà di Ingegneria dell Informazione, Informatica e Statistica Esercitazioni di PROGETTAZIONE DEL SOFTWARE (Corsi di Laurea in Ingegneria Informatica ed Automatica ed Ingegneria

Подробнее

SOMMARIO Coda (queue): QUEUE. QUEUE : specifica QUEUE

SOMMARIO Coda (queue): QUEUE. QUEUE : specifica QUEUE SOMMARIO Coda (queue): Specifica: interfaccia. Implementazione: Strutture indicizzate (array): Array di dimensione variabile. Array circolari. Strutture collegate (nodi). Prestazioni. Strutture Software

Подробнее

Multithreading in Java. Fondamenti di Sistemi Informativi 2014-2015

Multithreading in Java. Fondamenti di Sistemi Informativi 2014-2015 Multithreading in Java Fondamenti di Sistemi Informativi 2014-2015 Multithreading La programmazione concorrente consente di eseguire più processi o thread nello stesso momento. Nel secondo caso si parla

Подробнее

SISTEMI OPERATIVI. Deadlock (blocco critico) Domande di verifica. Luca Orrù Centro Multimediale Montiferru 04/06/2007

SISTEMI OPERATIVI. Deadlock (blocco critico) Domande di verifica. Luca Orrù Centro Multimediale Montiferru 04/06/2007 2007 SISTEMI OPERATIVI Deadlock (blocco critico) Domande di verifica Luca Orrù Centro Multimediale Montiferru 04/06/2007 Deadlock (blocco critico) 1. Si descriva il deadlock e le condizioni sotto cui si

Подробнее

Un esercizio d esame. Flavio De Paoli

Un esercizio d esame. Flavio De Paoli Un esercizio d esame e note sulla gestione dei dati Flavio De Paoli Il testo (Appello 22 ottobre 2001) Una stazione di servizio dispone di n distributori di benzina. I clienti si presentano a uno dei distributori

Подробнее

12 - Introduzione alla Programmazione Orientata agli Oggetti (Object Oriented Programming OOP)

12 - Introduzione alla Programmazione Orientata agli Oggetti (Object Oriented Programming OOP) 12 - Introduzione alla Programmazione Orientata agli Oggetti (Object Oriented Programming OOP) Programmazione e analisi di dati Modulo A: Programmazione in Java Paolo Milazzo Dipartimento di Informatica,

Подробнее

GESTIONE DEI PROCESSI

GESTIONE DEI PROCESSI Sistemi Operativi GESTIONE DEI PROCESSI Processi Concetto di Processo Scheduling di Processi Operazioni su Processi Processi Cooperanti Concetto di Thread Modelli Multithread I thread in Java Concetto

Подробнее

1. Che cos è la multiprogrammazione? Si può realizzare su un sistema monoprocessore? 2. Quali sono i servizi offerti dai sistemi operativi?

1. Che cos è la multiprogrammazione? Si può realizzare su un sistema monoprocessore? 2. Quali sono i servizi offerti dai sistemi operativi? 1. Che cos è la multiprogrammazione? Si può realizzare su un sistema monoprocessore? 2. Quali sono i servizi offerti dai sistemi operativi? 1. La nozione di multiprogrammazione prevede la possibilità di

Подробнее

Sistemi Operativi Esercizi Sincronizzazione

Sistemi Operativi Esercizi Sincronizzazione Sistemi Operativi Esercizi Sincronizzazione Docente: Claudio E. Palazzi [email protected] Esercizi Sincronizzazione Sistemi Operativi - Claudio Palazzi 14 Semafori (1) Semafori: variabili intere contano

Подробнее

Programmazione concorrente in Java. Dr. Paolo Casoto, Ph.D. - 2012 1

Programmazione concorrente in Java. Dr. Paolo Casoto, Ph.D. - 2012 1 + Programmazione concorrente in Java 1 + Introduzione al multithreading 2 La scomposizione in oggetti consente di separare un programma in sottosezioni indipendenti. Oggetto = metodi + attributi finalizzati

Подробнее

Corso di Informatica

Corso di Informatica Corso di Informatica Modulo T3 1-Sottoprogrammi 1 Prerequisiti Tecnica top-down Programmazione elementare 2 1 Introduzione Lo scopo di questa Unità è utilizzare la metodologia di progettazione top-down

Подробнее

FONDAMENTI di INFORMATICA L. Mezzalira

FONDAMENTI di INFORMATICA L. Mezzalira FONDAMENTI di INFORMATICA L. Mezzalira Possibili domande 1 --- Caratteristiche delle macchine tipiche dell informatica Componenti hardware del modello funzionale di sistema informatico Componenti software

Подробнее

Con il termine Sistema operativo si fa riferimento all insieme dei moduli software di un sistema di elaborazione dati dedicati alla sua gestione.

Con il termine Sistema operativo si fa riferimento all insieme dei moduli software di un sistema di elaborazione dati dedicati alla sua gestione. Con il termine Sistema operativo si fa riferimento all insieme dei moduli software di un sistema di elaborazione dati dedicati alla sua gestione. Compito fondamentale di un S.O. è infatti la gestione dell

Подробнее

Terza Esercitazione. Unix - Esercizio 1. Unix System Call Exec Java Introduzione Thread

Terza Esercitazione. Unix - Esercizio 1. Unix System Call Exec Java Introduzione Thread Terza Esercitazione Unix System Call Exec Java Introduzione Thread Stefano Monti [email protected] Unix - Esercizio 1 Scrivere un programma C con la seguente interfaccia:./compilaedesegui

Подробнее

Realizzazione di una classe con un associazione

Realizzazione di una classe con un associazione Realizzazione di una classe con un associazione Nel realizzare una classe che è coinvolta in un associazione, ci dobbiamo chiedere se la classe ha responsabilità sull associazione. Diciamo che una classe

Подробнее

Oggetti Lezione 3. aspetti generali e definizione di classi I

Oggetti Lezione 3. aspetti generali e definizione di classi I Programmazione a Oggetti Lezione 3 Il linguaggio Java: aspetti generali e definizione di classi I Sommario Storia e Motivazioni Definizione di Classi Campi e Metodi Istanziazione di oggetti Introduzione

Подробнее

Informatica 3. Informatica 3. LEZIONE 6: Il controllo dell esecuzione. Lezione 6 - Modulo 1. Errori durante l esecuzione. Il controllo dell esecuzione

Informatica 3. Informatica 3. LEZIONE 6: Il controllo dell esecuzione. Lezione 6 - Modulo 1. Errori durante l esecuzione. Il controllo dell esecuzione Informatica 3 Informatica 3 LEZIONE 6: Il controllo dell esecuzione Modulo 1: La gestione delle eccezioni Modulo 2: Programmazione concorrente Lezione 6 - Modulo 1 La gestione delle eccezioni Politecnico

Подробнее

La struttura dati ad albero binario

La struttura dati ad albero binario La struttura dati ad albero binario L albero è una struttura dati nella quale le informazioni sono organizzate in modo gerarchico, dall alto verso il basso. Gli elementi di un albero si chiamano nodi,

Подробнее

Sistemi Operativi GESTIONE DELLA MEMORIA SECONDARIA. D. Talia - UNICAL. Sistemi Operativi 11.1

Sistemi Operativi GESTIONE DELLA MEMORIA SECONDARIA. D. Talia - UNICAL. Sistemi Operativi 11.1 GESTIONE DELLA MEMORIA SECONDARIA 11.1 Memoria Secondaria Struttura del disco Scheduling del disco Gestione del disco Gestione dello spazio di swap Struttura RAID Affidabilità Implementazione della memoria

Подробнее

Sistemi Operativi. Memoria Secondaria GESTIONE DELLA MEMORIA SECONDARIA. Struttura del disco. Scheduling del disco. Gestione del disco

Sistemi Operativi. Memoria Secondaria GESTIONE DELLA MEMORIA SECONDARIA. Struttura del disco. Scheduling del disco. Gestione del disco GESTIONE DELLA MEMORIA SECONDARIA 11.1 Memoria Secondaria Struttura del disco Scheduling del disco Gestione del disco Gestione dello spazio di swap Struttura RAID Affidabilità Implementazione della memoria

Подробнее

Algoritmi di Ricerca. Esempi di programmi Java

Algoritmi di Ricerca. Esempi di programmi Java Fondamenti di Informatica Algoritmi di Ricerca Esempi di programmi Java Fondamenti di Informatica - D. Talia - UNICAL 1 Ricerca in una sequenza di elementi Data una sequenza di elementi, occorre verificare

Подробнее

Funzioni in C. Violetta Lonati

Funzioni in C. Violetta Lonati Università degli studi di Milano Dipartimento di Scienze dell Informazione Laboratorio di algoritmi e strutture dati Corso di laurea in Informatica Funzioni - in breve: Funzioni Definizione di funzioni

Подробнее

progam ponteasensounicoalaternato ; type dir = ( nord, sud );

progam ponteasensounicoalaternato ; type dir = ( nord, sud ); Esercizio di Sincronizzazione Tra Processi: Ponte a Senso Unico Alternato Un ponte contiene una sola csia di traffico consentendo così l'accesso a macchine provenienti da una sola direzione per volta,

Подробнее

Progettazione : Design Pattern Creazionali

Progettazione : Design Pattern Creazionali Progettazione : Design Pattern Creazionali Alessandro Martinelli [email protected] 30 Novembre 2010 Progettazione : Design Pattern Creazionali Aspetti generali dei Design Pattern Creazionali

Подробнее

Prova di Laboratorio di Programmazione

Prova di Laboratorio di Programmazione Prova di Laboratorio di Programmazione 6 febbraio 015 ATTENZIONE: Non è possibile usare le classi del package prog.io del libro di testo. Oltre ai metodi richiesti in ciascuna classe, è opportuno implementare

Подробнее

Registratori di Cassa

Registratori di Cassa modulo Registratori di Cassa Interfacciamento con Registratore di Cassa RCH Nucleo@light GDO BREVE GUIDA ( su logiche di funzionamento e modalità d uso ) www.impresa24.ilsole24ore.com 1 Sommario Introduzione...

Подробнее

Corso di Sistemi Operativi Ingegneria Elettronica e Informatica prof. Rocco Aversa. Raccolta prove scritte. Prova scritta

Corso di Sistemi Operativi Ingegneria Elettronica e Informatica prof. Rocco Aversa. Raccolta prove scritte. Prova scritta Corso di Sistemi Operativi Ingegneria Elettronica e Informatica prof. Rocco Aversa Raccolta prove scritte Realizzare una classe thread Processo che deve effettuare un numero fissato di letture da una memoria

Подробнее

Corso di Laurea in Ingegneria Gestionale Esame di Informatica a.a. 2010-11 13 settembre 2011

Corso di Laurea in Ingegneria Gestionale Esame di Informatica a.a. 2010-11 13 settembre 2011 Cognome Nome Matricola Postazione PC Corso di Laurea in Ingegneria Gestionale Esame di Informatica a.a. 2010-11 13 settembre 2011 Testo Il database di un videonoleggio è costituito da due vettori paralleli.

Подробнее

CIRCOLARE RILEVA WEB del 19/05/2009

CIRCOLARE RILEVA WEB del 19/05/2009 M:\Manuali\Rileva Web\Treviso\Circolare 19052009.doc CIRCOLARE RILEVA WEB del 19/05/2009 1. FILTRO DIPENDENTI...2 1.1. CREAZIONE TABELLA FILTRI...2 1.2. SEGNALAZIONE ESPORTAZIONE...3 1.3. ELIMINAZIONE

Подробнее

Il descrittore di processo (PCB)

Il descrittore di processo (PCB) Il descrittore di processo (PC) Il S.O. gestisce i processi associando a ciascuno di essi un struttura dati di tipo record detta descrittore di processo o Process Control lock (PC) Il PC contiene tutte

Подробнее

ACCESSO AL SISTEMA HELIOS...

ACCESSO AL SISTEMA HELIOS... Manuale Utente (Gestione Formazione) Versione 2.0.2 SOMMARIO 1. PREMESSA... 3 2. ACCESSO AL SISTEMA HELIOS... 4 2.1. Pagina Iniziale... 6 3. CARICAMENTO ORE FORMAZIONE GENERALE... 9 3.1. RECUPERO MODELLO

Подробнее

Un sistema operativo è un insieme di programmi che consentono ad un utente di

Un sistema operativo è un insieme di programmi che consentono ad un utente di INTRODUZIONE AI SISTEMI OPERATIVI 1 Alcune definizioni 1 Sistema dedicato: 1 Sistema batch o a lotti: 2 Sistemi time sharing: 2 Sistema multiprogrammato: 3 Processo e programma 3 Risorse: 3 Spazio degli

Подробнее

(Esercizi Tratti da Temi d esame degli ordinamenti precedenti)

(Esercizi Tratti da Temi d esame degli ordinamenti precedenti) (Esercizi Tratti da Temi d esame degli ordinamenti precedenti) Esercizio 1 L'agenzia viaggi GV - Grandi Viaggi vi commissiona l'implementazione della funzione AssegnaVolo. Tale funzione riceve due liste

Подробнее

Scheduling della CPU. Sistemi multiprocessori e real time Metodi di valutazione Esempi: Solaris 2 Windows 2000 Linux

Scheduling della CPU. Sistemi multiprocessori e real time Metodi di valutazione Esempi: Solaris 2 Windows 2000 Linux Scheduling della CPU Sistemi multiprocessori e real time Metodi di valutazione Esempi: Solaris 2 Windows 2000 Linux Sistemi multiprocessori Fin qui si sono trattati i problemi di scheduling su singola

Подробнее

LA SINCRONIZZAZIONE TRA PROCESSI

LA SINCRONIZZAZIONE TRA PROCESSI LA SINCRONIZZAZIONE TRA PROCESSI E' più complesso scrivere programmi concorrenti rispetto a programmi sequenziali in quanto non basta essere sicuri della correttezza dei singoli moduli ma è necessario

Подробнее

Thread: sincronizzazione Esercitazioni del 09 Ottobre 2009

Thread: sincronizzazione Esercitazioni del 09 Ottobre 2009 Thread: sincronizzazione Esercitazioni del 09 Ottobre 2009 Luca Fossati, Fabrizio Castro, Vittorio Zaccaria October 10, 2009 Sincronizzazione - 1 1 Esercizio 1: Sincronizzazione - 1 Qual è il problema

Подробнее

I file di dati. Unità didattica D1 1

I file di dati. Unità didattica D1 1 I file di dati Unità didattica D1 1 1) I file sequenziali Utili per la memorizzazione di informazioni testuali Si tratta di strutture organizzate per righe e non per record Non sono adatte per grandi quantità

Подробнее

Deadlock (stallo) Parte III. Deadlock

Deadlock (stallo) Parte III. Deadlock Parte III Deadlock Sistemi Operativi - prof. Silvio Salza - a.a. 2008-2009 III - 1 Deadlock (stallo) Su di un tavolo ci sono un piatto ed una forchetta A e B sono seduti al tavolo, per mangiare ciascuno

Подробнее

Inizializzazione, Assegnamento e Distruzione di Classi

Inizializzazione, Assegnamento e Distruzione di Classi Inizializzazione, Assegnamento e Distruzione di Classi Lezione 9 Operazioni Automatiche In ogni programma C++ oggetti classe vengono gestiti automaticamente dal compilatore Inizializzati al momento della

Подробнее

Java: Compilatore e Interprete

Java: Compilatore e Interprete Java: Compilatore e Interprete Java Virtual Machine Il bytecode non è Linguaggio Macchina. Per diventarlo, deve subire un ulteriore trasformazione che viene operata dall interprete Java in modalità JIT

Подробнее

APPUNTI DI MATEMATICA LE FRAZIONI ALGEBRICHE ALESSANDRO BOCCONI

APPUNTI DI MATEMATICA LE FRAZIONI ALGEBRICHE ALESSANDRO BOCCONI APPUNTI DI MATEMATICA LE FRAZIONI ALGEBRICHE ALESSANDRO BOCCONI Indice 1 Le frazioni algebriche 1.1 Il minimo comune multiplo e il Massimo Comun Divisore fra polinomi........ 1. Le frazioni algebriche....................................

Подробнее

5.2.1 RELAZIONI TRA TABELLE 1. 5.2.4.1 Creare una relazione uno-a-uno, uno-a-molti tra tabelle 9

5.2.1 RELAZIONI TRA TABELLE 1. 5.2.4.1 Creare una relazione uno-a-uno, uno-a-molti tra tabelle 9 5.2.1 RELAZIONI TRA TABELLE 1 5.2.4.1 Creare una relazione uno-a-uno, uno-a-molti tra tabelle 9 Il grado di un verso di un associazione indica quanti record della tabella di partenza si associano ad un

Подробнее

Telematica II 17. Esercitazione/Laboratorio 6

Telematica II 17. Esercitazione/Laboratorio 6 Multitasking e Multithreading Telematica II 17. Esercitazione/Laboratorio 6 Multitasking si riferisce all abilità di un computer di eseguire processi (jobs) multipli in maniera concorrente si ricorda che

Подробнее

http://www.programmiamo.altervista.org/c/oop/o...

http://www.programmiamo.altervista.org/c/oop/o... PROGRAMMIAMO Programma per la gestione di un conto corrente C++ - Costruttore e distruttore C++ Home Contatti Supponiamo ora di voler scrivere un programma a menu per la gestione di un conto corrente bancario.

Подробнее

Programmazione concorrente in Java

Programmazione concorrente in Java Programmazione concorrente in Java Multithreading in Java Ogni thread e un oggetto, creato come istanza della classe java.lang.thread La classe Thread contiene tutti i metodi per gestire i threads L utente

Подробнее

appunti delle lezioni Architetture client/server: applicazioni server

appunti delle lezioni Architetture client/server: applicazioni server Sistemi informativi applicati (reti di calcolatori): appunti delle lezioni Architetture /: applicazioni 1 La logica dei Abbiamo visto che un applicazione si connette e comunica con un applicazione mediante

Подробнее

Corso di Linguaggi di Programmazione

Corso di Linguaggi di Programmazione Corso di Linguaggi di Programmazione Lezione 19 Alberto Ceselli [email protected] Dipartimento di Tecnologie dell Informazione Università degli Studi di Milano 18 Maggio 2010 idea: sfruttare i

Подробнее

Esercizi sugli Oggetti Monitor

Esercizi sugli Oggetti Monitor Esercizi sugli Oggetti Monitor Esercitazione di Laboratorio di Programmazione di Rete A Daniele Sgandurra Università di Pisa 29/10/2008 Wait e Notify Ogni oggetto in Java ha un lock implicito. Il lock

Подробнее

Esercitazioni di Progettazione del Software. Esercitazione (Prova al calcolatore del 17 settembre 2010)

Esercitazioni di Progettazione del Software. Esercitazione (Prova al calcolatore del 17 settembre 2010) Sapienza - Università di Roma Facoltà di Ingegneria dell Informazione, Informatica e Statistica Corso di Laurea in Ingegneria Informatica ed Automatica, Ingegneria dei Sistemi Informatici Esercitazioni

Подробнее

Corso di Informatica

Corso di Informatica Corso di Informatica Modulo T Scorrimento-Rotazione-Ricerca Prerequisiti Programmazione elementare Conoscenza ed uso di vettori Introduzione Lo scopo di questa Unità è approfondire il concetto di vettore

Подробнее

Computazione multi-processo. Condivisione, Comunicazione e Sincronizzazione dei Processi. Segnali. Processi e Threads Pt. 2

Computazione multi-processo. Condivisione, Comunicazione e Sincronizzazione dei Processi. Segnali. Processi e Threads Pt. 2 Computazione multi-processo Avere più processi allo stesso momento implica/richiede Processi e Threads Pt. 2 Concorrenza ed efficienza Indipendenza e protezione dei dati ma deve prevedere/permettere anche:

Подробнее

Matematica in laboratorio

Matematica in laboratorio Unità 1 Attività guidate Attività 1 Foglio elettronico Divisibilità tra numeri naturali Costruisci un foglio di lavoro per determinare se a è divisibile per b, essendo a e b due numeri naturali, con a

Подробнее

Synchronized (ancora)

Synchronized (ancora) Synchronized (ancora) Riscriviamo l esempio di prima. Usiamo una struttura modulare, con una classe Notificatore che ha opportuni metodi. La classe ha due campi privati, la lista buftext e un suo thread.

Подробнее

Mac Application Manager 1.3 (SOLO PER TIGER)

Mac Application Manager 1.3 (SOLO PER TIGER) Mac Application Manager 1.3 (SOLO PER TIGER) MacApplicationManager ha lo scopo di raccogliere in maniera centralizzata le informazioni piu salienti dei nostri Mac in rete e di associare a ciascun Mac i

Подробнее

Esercitazione finale per il corso di Sistemi Operativi (A.A. 2004/2005)

Esercitazione finale per il corso di Sistemi Operativi (A.A. 2004/2005) Esercitazione finale per il corso di Sistemi Operativi (A.A. 2004/2005) Descrizione dell esercitazione L esercitazione consiste nell implementare un semplice gestore di aste attraverso il quale gli utenti

Подробнее

LE FUNZIONI A DUE VARIABILI

LE FUNZIONI A DUE VARIABILI Capitolo I LE FUNZIONI A DUE VARIABILI In questo primo capitolo introduciamo alcune definizioni di base delle funzioni reali a due variabili reali. Nel seguito R denoterà l insieme dei numeri reali mentre

Подробнее

Gestione Turni. Introduzione

Gestione Turni. Introduzione Gestione Turni Introduzione La gestione dei turni di lavoro si rende necessaria quando, per garantire la continuità del servizio di una determinata struttura, è necessario che tutto il personale afferente

Подробнее

Gestione della memoria centrale

Gestione della memoria centrale Gestione della memoria centrale Un programma per essere eseguito deve risiedere in memoria principale e lo stesso vale per i dati su cui esso opera In un sistema multitasking molti processi vengono eseguiti

Подробнее

Esercizi Capitolo 6 - Alberi binari di ricerca

Esercizi Capitolo 6 - Alberi binari di ricerca Esercizi Capitolo 6 - Alberi binari di ricerca Alberto Montresor 23 settembre 200 Alcuni degli esercizi che seguono sono associati alle rispettive soluzioni. Se il vostro lettore PDF lo consente, è possibile

Подробнее

Programmazione a Oggetti Lezione 10. Ereditarieta

Programmazione a Oggetti Lezione 10. Ereditarieta Programmazione a Oggetti Lezione 10 Ereditarieta Sommario Come definire sottoclassi Costruttori Abstract Classes Final Ereditarietà: promemoria Strumento tipico dell OOP per riusare il codice e creare

Подробнее

Modulo 4: Ereditarietà, interfacce e clonazione

Modulo 4: Ereditarietà, interfacce e clonazione Modulo 4: Ereditarietà, interfacce e clonazione Argomenti Trattati: Classi, Superclassi e Sottoclassi Ereditarietà Ereditarietà ed Attributi Privati Override super Ereditarietà e Costruttori Polimorfismo

Подробнее

LABORATORIO DI PROGRAMMAZIONE 2012 2013 EDIZIONE 1, TURNO B

LABORATORIO DI PROGRAMMAZIONE 2012 2013 EDIZIONE 1, TURNO B LABORATORIO DI PROGRAMMAZIONE 2012 2013 EDIZIONE 1, TURNO B 23.XI.2012 VINCENZO MARRA Indice Esercizio 1 1 Menu 1 Tempo: 35 min. 2 Commento 1 2 Esercizio 2 2 Ordinamento e ricerca binaria con la classe

Подробнее

COLLI. Gestione dei Colli di Spedizione. Release 5.20 Manuale Operativo

COLLI. Gestione dei Colli di Spedizione. Release 5.20 Manuale Operativo Release 5.20 Manuale Operativo COLLI Gestione dei Colli di Spedizione La funzione Gestione Colli consente di generare i colli di spedizione in cui imballare gli articoli presenti negli Ordini Clienti;

Подробнее

Siti web centrati sui dati Architettura MVC-2: i JavaBeans

Siti web centrati sui dati Architettura MVC-2: i JavaBeans Siti web centrati sui dati Architettura MVC-2: i JavaBeans 1 ALBERTO BELUSSI ANNO ACCADEMICO 2009/2010 Limiti dell approccio SEVLET UNICA La servlet svolge tre tipi di funzioni distinte: Interazione con

Подробнее

10 - Programmare con gli Array

10 - Programmare con gli Array 10 - Programmare con gli Array Programmazione e analisi di dati Modulo A: Programmazione in Java Paolo Milazzo Dipartimento di Informatica, Università di Pisa http://www.di.unipi.it/ milazzo milazzo di.unipi.it

Подробнее

Linguaggi Corso M-Z - Laurea in Ingegneria Informatica A.A. 2007-2008. Esercitazione. Programmazione Object Oriented in Java

Linguaggi Corso M-Z - Laurea in Ingegneria Informatica A.A. 2007-2008. Esercitazione. Programmazione Object Oriented in Java Linguaggi Corso M-Z - Laurea in Ingegneria Informatica A.A. 2007-2008 Alessandro Longheu http://www.diit.unict.it/users/alongheu [email protected] Programmazione Object Oriented in Java

Подробнее

Memoria secondaria. Struttura del disco. Scheduling del disco. Gestione dell unità a disco. Affidabilità dei dischi: RAID

Memoria secondaria. Struttura del disco. Scheduling del disco. Gestione dell unità a disco. Affidabilità dei dischi: RAID Memoria secondaria Struttura del disco Scheduling del disco Gestione dell unità a disco Affidabilità dei dischi: RAID Sistemi Operativi 13.1 Struttura del disco I dischi vengono indirizzati come grandi

Подробнее

Introduzione ai Metodi Formali

Introduzione ai Metodi Formali Intruzione ai Meti Formali Sistemi software anche molto complessi regolano la vita quotidiana, anche in situazioni life-critical (e.g. avionica) e business-critical (e.g. operazioni bancarie). Esempi di

Подробнее

B+Trees. Introduzione

B+Trees. Introduzione B+Trees Introduzione B+Trees Il B+Trees e la variante maggiormente utilizzata dei BTrees BTrees e B+trees fanno parte della famiglia degli alberi di ricerca. Nel B+Trees i dati sono memorizzati solo nelle

Подробнее

Sistemi Operativi. Lezione 7 Comunicazione tra processi

Sistemi Operativi. Lezione 7 Comunicazione tra processi Lezione 7 Comunicazione tra processi Introduzione La soluzione sw al problema della mutua esclusione è abbastanza complessa Algoritmo di Peterson La soluzione hw mediante disabilitazione degli interrupt

Подробнее

La gestione dell input/output da tastiera La gestione dell input/output da file La gestione delle eccezioni

La gestione dell input/output da tastiera La gestione dell input/output da file La gestione delle eccezioni La gestione dell input/output da tastiera La gestione dell input/output da file La gestione delle eccezioni Autore: Prof. Agostino Sorbara ITIS "M. M. Milano" Autore: Prof. Agostino Sorbara ITIS "M. M.

Подробнее

MANUALE ESSE3 Gestione Registro delle lezioni

MANUALE ESSE3 Gestione Registro delle lezioni MANUALE ESSE3 Gestione Registro delle lezioni DOCENTI 1 INDICE 1. INTRODUZIONE E ACCESSO... 3 2. GESTIONE DEL REGISTRO... 4 2.1. Informazioni generali... 6 2.2. Stato del Registro... 7 2.2.1. Transizioni

Подробнее

Esercizio 1: trading on-line

Esercizio 1: trading on-line Esercizio 1: trading on-line Si realizzi un programma Java che gestisca le operazioni base della gestione di un fondo per gli investimenti on-line Creazione del fondo (con indicazione della somma in inizialmente

Подробнее

Istituto Centrale per il Catalogo Unico delle Biblioteche Italiane. e per le Informazioni bibliografiche. Manuali utente per SBN WEB. Versione 1.

Istituto Centrale per il Catalogo Unico delle Biblioteche Italiane. e per le Informazioni bibliografiche. Manuali utente per SBN WEB. Versione 1. Istituto Centrale per il Catalogo Unico delle Biblioteche Italiane e per le Informazioni bibliografiche Manuali utente per SBN WEB Versione 1.0 Produzione editoriale Vers. 1.0 27/09/2013 Pagina 1 Sommario

Подробнее

Consiglio regionale della Toscana. Regole per il corretto funzionamento della posta elettronica

Consiglio regionale della Toscana. Regole per il corretto funzionamento della posta elettronica Consiglio regionale della Toscana Regole per il corretto funzionamento della posta elettronica A cura dell Ufficio Informatica Maggio 2006 Indice 1. Regole di utilizzo della posta elettronica... 3 2. Controllo

Подробнее

Risolvere un problema significa individuare un procedimento che permetta di arrivare al risultato partendo dai dati

Risolvere un problema significa individuare un procedimento che permetta di arrivare al risultato partendo dai dati Algoritmi Algoritmi Risolvere un problema significa individuare un procedimento che permetta di arrivare al risultato partendo dai dati Il procedimento (chiamato algoritmo) è composto da passi elementari

Подробнее

2.0 Gli archivi. 2.1 Inserire gli archivi. 2.2 Archivio Clienti, Fornitori, Materiali, Noleggi ed Altri Costi. Impresa Edile Guida all uso

2.0 Gli archivi. 2.1 Inserire gli archivi. 2.2 Archivio Clienti, Fornitori, Materiali, Noleggi ed Altri Costi. Impresa Edile Guida all uso 2.0 Gli archivi All interno della sezione archivi sono inserite le anagrafiche. In pratica si stratta di tutti quei dati che ricorreranno costantemente all interno dei documenti. 2.1 Inserire gli archivi

Подробнее

Nuova procedura di Cassa Contanti Wingesfar: istruzioni per le farmacie Novembre 2009

Nuova procedura di Cassa Contanti Wingesfar: istruzioni per le farmacie Novembre 2009 Nuova procedura di Cassa Contanti Wingesfar: istruzioni per le farmacie Novembre 2009 Documenti Tecnici Informatica e Farmacia Vega S.p.A. Premessa La procedura di Cassa Contanti rileva i movimenti giornalieri

Подробнее

Capitolo 7: Sincronizzazione

Capitolo 7: Sincronizzazione Capitolo 7: Sincronizzazione Il problema della sincronizzazione. Il problema della sezione critica. Hardware per la sincronizzazione. Semafori. Problemi classici di sincronizzazione. Monitor (cenni). 7.1

Подробнее

Introduzione alla programmazione in C

Introduzione alla programmazione in C Introduzione alla programmazione in C Testi Consigliati: A. Kelley & I. Pohl C didattica e programmazione B.W. Kernighan & D. M. Ritchie Linguaggio C P. Tosoratti Introduzione all informatica Materiale

Подробнее

Il problema del produttore e del consumatore. Cooperazione tra processi

Il problema del produttore e del consumatore. Cooperazione tra processi Il problema del produttore e del consumatore Cooperazione tra processi Risorsa consumabile I processi disgiunti possono interferire tra loro a causa dell'uso di risorse permanenti, ma ognuno di essi ignora

Подробнее

Architettura MVC-2: i JavaBeans

Architettura MVC-2: i JavaBeans Siti web centrati sui dati Architettura MVC-2: i JavaBeans Alberto Belussi anno accademico 2008/2009 Limiti dell approccio SEVLET UNICA La servlet svolge tre tipi di funzioni distinte: Interazione con

Подробнее

Tricks & Tips. [Access] Tutorial - ActiveX - Controllo Tree View. - Michele de Nittis - Versione: 1 Data Versione: venerdì 30 agosto 2002

Tricks & Tips. [Access] Tutorial - ActiveX - Controllo Tree View. - Michele de Nittis - Versione: 1 Data Versione: venerdì 30 agosto 2002 Tricks & Tips [Access] - Michele de Nittis - Tutorial - ActiveX - Controllo Tree View Versione: 1 Data Versione: venerdì 30 agosto 2002 1 SOMMARIO PREMESSA...3 INSERIMENTO DEL CONTROLLO...3 AGGIUNTA DELLE

Подробнее

Corso di Laurea Ingegneria Informatica Fondamenti di Informatica 2

Corso di Laurea Ingegneria Informatica Fondamenti di Informatica 2 Corso di Laurea Ingegneria Informatica Fondamenti di Informatica 2 Dispensa E08 Soluzione Esercizi F. Gasparetti, C. Limongelli Marzo 2008 http://www.dia.uniroma3.it/~java/fondinf1/ Soluzione Esercizi

Подробнее