D. Rosaci I Processi Definizione di Processo • Processo: Programma in esecuzione • Problematiche Classiche – Gestione – Scheduling • Problematiche nei SD – – – – D. Rosaci Multi-threading Virtualizzazione Processi Client e Processi Server Mobilità tra processi Sistemi Distribuiti: I Processi 2 Processi: Concetti di base • Nel corso della sua attività il S.O. crea una serie di Processori Virtuali, ad ognuno dei quali è assegnato un processo (programma in esecuzione) • Il S.O. ha cura che i singoli processi non si disturbino a vicenda: è reso trasparente il fatto che i processi utilzzano la stessa CPU. • Prezzo della Trasparenza alla Concorrenza: – ogni processo deve avere uno spazio degli indirizzi indipendente – Si devono gestire gli switch da un processo all’altro D. Rosaci Sistemi Distribuiti: I Processi 3 Dai Processi ai Thread • Come un processo, anche un thread esegue un suo pezzo di codice, indipendentemente dagli altri thread. • A differenza dei processi, non c’è però un alto grado di trasparenza alla concorrenza • Infatti, un sistema a thread gestisce solo l’insieme minimo delle informazioni per permettere alla CPU di essere condivisa da più thread • Il contesto di un thread è composto solo dal contesto della CPU e da qualche altra informazione sui thread in esecuzione (ad esempio un thread è bloccato e non può essere utilizzato) • E’ il programmatore che deve proteggere i dati da accessi scorretti da parte dei thread • Vantaggio rispetto ai processi: Prestazioni generalmente migliori, al prezzo di uno sforzo intellettuale da parte del programmatore D. Rosaci Sistemi Distribuiti: I Processi 4 Ma come si usano i thread? • Si usano per scomporre un processo in sotto parti elementari indipendenti • Nei processi a singolo thread, quando si esegue una chiamata a sistema bloccante, si blocca tutto il processo • Esempio: in un foglio elettronico, quando si inseriscono dati in una cella occorre poi eseguire computazioni che si ripercuotono su tutte le altre celle • Con un solo thread, mentre si inseriscono i dati non si effettuano computazioni, e viceversa • E’ più efficiente usare due thread, uno per gestire l’input della cella, l’altro per gestire le computazioni • Un altro grande vantaggio nel multi-threading si ha nei sistemi multiprocessore: ogni thread può essere assegnato ad un processore e ciò permette l’esecuzione parallela mentre i dati stanno su una memoria centrale condivisa (es. i server nelle applicazioni client-server) D. Rosaci Sistemi Distribuiti: I Processi 5 Semplice esempio public class SimpleThread extends Thread{ private int countDown=100; private static int threadCount=0; public SimpleThread(){ super(""+ ++threadCount); start(); } public String toString(){ return "#"+getName()+":"+countDown; } public void run(){ while(true){ System.out.println(this); if(--countDown==0) return; } } public static void main(String[] args) { for(int i=0;i<100;i++) new SimpleThread(); } } D. Rosaci Sistemi Distribuiti: I Processi Il programma crea cinque distinti thread, ognuno avente nome dato dalla variabile statica threadCount Ogni thread ha il compito di contare da 100 a 1, a ritroso L’esecuzione a video ha effetto imprevedibile, dovuto al fatto che i thread sono eseguiti indipendentemente, con una politica di assegnamento della CPU dipendente dalla JVM Quindi un thread può essere interrotto mentre sta calcolando! 6 Semplice esempio public class SimpleThread extends Thread{ private int countDown=100; private static int threadCount=0; public SimpleThread(){ super(""+ ++threadCount); start(); } public String toString(){ return "#"+getName()+":"+countDown; } public void run(){ while(true){ System.out.println(this); if(--countDown==0) return; } } public static void main(String[] args) { for(int i=0;i<100;i++) new SimpleThread(); } } D. Rosaci Sistemi Distribuiti: I Processi Il programma crea cinque distinti thread, ognuno avente nome dato dalla variabile statica threadCount Ogni thread ha il compito di contare da 100 a 1, a ritroso L’esecuzione a video ha effetto imprevedibile, dovuto al fatto che i thread sono eseguiti indipendentemente, con una politica di assegnamento della CPU dipendente dalla JVM Quindi un thread può essere interrotto mentre sta calcolando! 7 Uso di sleep() public class SleepingThread extends Thread{ private int countDown=100; private static int threadCount=0; Non si ottiene molto: i thread public SleepingThread(){ continuano ad essere eseguiti super(""+ ++threadCount); indipendentemente start(); } public String toString(){ return "#"+getName()+":"+countDown; } public void run(){ while(true){ System.out.println(this); if(- -countDown==0) return; try{sleep(100) ;} catch(IinterruptedException e) { throw new RuntimeException(e); } } } public static void main(String[] args) { for(int i=0;i<100;i++) new SleepingThread(); } } D. Rosaci Sistemi Distribuiti: I Processi 8 Uso di sleep() e join() public class SleepingThread extends Thread{ private int countDown=100; private static int threadCount=0; Il metodo main() attende il public SleepingThread(){ completamento del thread super(""+ ++threadCount); prima di procedere con start(); l’esecuzione: il programma si } comporta adesso in modo public String toString(){ deterministico return "#"+getName()+":"+countDown; } public void run(){ while(true){ System.out.println(this); if(- -countDown==0) return; try{sleep(100) ;} catch(IinterruptedException e) { throw new RuntimeException(e); } } } public static void main(String[] args) { for(int i=0;i<100;i++) new SleepingThread().join(); } } D. Rosaci Sistemi Distribuiti: I Processi 9 Thread nei SD • Vantaggio: rendono più semplice la gestione di connessioni logiche multiple • Due aspetti specifici da considerare: – Client multithread – Server multithread D. Rosaci Sistemi Distribuiti: I Processi 10 Client Multithread • • • • • • Un obiettivo dei sistemi distribuiti è quello di raggiungere un alto grado di trasparenza alla distribuzione Nelle reti globali, ciò comporta la necessità di nascondere i lunghi tempi di propagazione dei messaggi tra i processi (ordine delle centinai di millisec., o addirittura dei secondi) Metodo per nascondere la latenza nella comunicazione: avviare la comunicazione stessa e immediatamente iniziare a fare qualcos’altro Esempio: Browser Web: quando si carica una pagina Web, si prelevano dati spesso molto “pesanti” come immagini o oggetti multimediali. Per nascondere la latenza, il Browser spesso comincia a visualizzare i dati disponibili mentre ancora la comunicazione è in corso Non appena il file HTML è stato prelevato, si possono lanciare più thread indipendenti per prelevare i vari dati. Se un thread si blocca, gli altri non ne risentono Altro vantaggio: se il server è effettivamente replicato su più macchine per gestire flussi elevati di richieste, un client multi-thread può ottenere performance migliori perché è altamente probabile che i vari thread verrano eseguiti (in parallelo) da server differenti D. Rosaci Sistemi Distribuiti: I Processi 11 Server Multithread • • • • • Utilizzo principale del multithreading nei SD: lato server Semplifica notevolmente la scrittura del codice di un server Si consideri ad esempio un file server che occasionalmente deve bloccarsi in attesa Un file server attende la richiesta di un’operazione su un file, quindi la soddisfa ed invia la risposta Organizzazione possibile: – Un thread, il dispacher, legge le richieste in ingresso – Le richieste sono inviate dai client al server ad una porta ben conosciuta – Il server esamina la richiesta, sceglie un worker thread inattivo e gliela passa – Il worker va avanti eseguendo una lettura bloccante sul file system locale del server – Il worker può rimanere bloccato in attesa dei dati da disco. Ma questo non blocca né il dispatcher ne gli altri worker thread – Nota: senza il multithreading, il server rimarrebbe bloccato sulla singola richiesta, senza poter servire altre richieste. – Questo è un altro esempio di come i thread generalmente migliorino le prestazioni D. Rosaci Sistemi Distribuiti: I Processi 12 Esempio: Processo Server in JAVA • Vogliamo scrivere il codice di un programma server in Java • Per farlo, dobbiamo introdurre due concetti base del linguaggio Java: – Socket – Thread D. Rosaci Sistemi Distribuiti: I Processi 13 Socket • Un socket è una sorta di “terminazione” software di un collegamento bidirezionale tra un programma server ed uno o più programmi client • Un socket associa al programma server una specifica porta hardware sulla macchina su cui è eseguito, in modo tale che ogni programma client che sta in qualunque altro luogo nella rete con un socket associato a quella stessa porta può comunicare col programma server D. Rosaci Sistemi Distribuiti: I Processi 14 Client D. Rosaci Sistemi Distribuiti: I Processi 15 Codice del Client - 1 import java.awt.Color; import java.awt.BorderLayout; import java.awt.event.*; import javax.swing.*; import java.io.*; import java.net.*; class SocketClient extends JFrame implements ActionListener { JLabel text, clicked; JButton button;JPanel panel; JTextField textField; Socket socket = null; PrintWriter out = null; BufferedReader in = null; ……..continua D. Rosaci Sistemi Distribuiti: I Processi 16 Codice del Client - 2 SocketClient(){ text = new JLabel("Text to send over socket:"); textField = new JTextField(20); button = new JButton("Click Me"); button.addActionListener(this); panel = new JPanel(); panel.setLayout(new BorderLayout()); panel.setBackground(Color.white); getContentPane().add(panel); panel.add("North", text); panel.add("Center", textField); panel.add("South", button); } //End Constructor D. Rosaci Sistemi Distribuiti: I Processi 17 Codice del Client - 3 public void actionPerformed(ActionEvent event){ Object source = event.getSource(); if(source == button){ //Send data over socket String text = textField.getText(); out.println(text); textField.setText(new String("")); //Receive text from server try{ String line = in.readLine(); System.out.println("Text received :" + line); } catch (IOException e){ System.out.println("Read failed"); System.exit(1); } } } D. Rosaci Sistemi Distribuiti: I Processi 18 Codice del Client - 4 public void listenSocket(){ //Create socket connection try{ socket = new Socket("kq6py", 4444); out = new PrintWriter(socket.getOutputStream(), true); in = new BufferedReader( new InputStreamReader(socket.getInputStream())); } catch (UnknownHostException e) { System.out.println("Unknown host"); System.exit(1); } catch (IOException e) { System.out.println("No I/O"); System.exit(1); } } D. Rosaci Sistemi Distribuiti: I Processi 19 Codice del Client - 5 public static void main(String[] args){ SocketClient frame = new SocketClient(); frame.setTitle("Client Program"); WindowListener l = new WindowAdapter() { public void windowClosing(WindowEvent e) { System.exit(0); } }; frame.addWindowListener(l); frame.pack(); frame.setVisible(true); frame.listenSocket(); } }//fine della classe SocketClient D. Rosaci Sistemi Distribuiti: I Processi 20 Server D. Rosaci Sistemi Distribuiti: I Processi 21 Codice del Server - 1 import java.awt.Color; import java.awt.BorderLayout; import java.awt.event.*; import javax.swing.*; import java.io.*; import java.net.*; class SocketServer extends JFrame implements ActionListener { JButton button; JLabel label = new JLabel("Text received over socket:"); JPanel panel; JTextArea textArea = new JTextArea(); ServerSocket server = null; Socket client = null; BufferedReader in = null; PrintWriter out = null; String line; D. Rosaci Sistemi Distribuiti: I Processi 22 Codice del Server - 2 SocketServer(){ //Begin Constructor button = new JButton("Click Me"); button.addActionListener(this); panel = new JPanel(); panel.setLayout(new BorderLayout()); panel.setBackground(Color.white); getContentPane().add(panel); panel.add("North", label); panel.add("Center", textArea); panel.add("South", button); } D. Rosaci Sistemi Distribuiti: I Processi 23 Codice del Server - 3 SocketServer(){ //Begin Constructor button = new JButton("Click Me"); button.addActionListener(this); panel = new JPanel(); panel.setLayout(new BorderLayout()); panel.setBackground(Color.white); getContentPane().add(panel); panel.add("North", label); panel.add("Center", textArea); panel.add("South", button); } public void actionPerformed(ActionEvent event) { Object source = event.getSource(); if(source == button){ textArea.setText(line); } } D. Rosaci Sistemi Distribuiti: I Processi 24 Codice del Server - 4 public void listenSocket(){ try{ server = new ServerSocket(4444); } catch (IOException e) { System.out.println("Could not listen on port 4444"); System.exit(-1) } try{ client = server.accept(); } catch (IOException e) { System.out.println("Accept failed: 4444"); System.exit(-1); } try{ in = new BufferedReader(new InputStreamReader(client.getInputStream())); out = new PrintWriter(client.getOutputStream(), true); } catch (IOException e) { System.out.println("Accept failed: 4444"); System.exit(-1); } ….CONTINUA D. Rosaci Sistemi Distribuiti: I Processi 25 Codice del Server - 5 while(true){ try{ line = in.readLine(); //Send data back to client out.println(line); } catch (IOException e) { System.out.println("Read failed"); System.exit(-1); } } } //Fine funzione listenSocket protected void finalize(){ //Clean up try{ in.close(); out.close(); server.close(); } catch (IOException e) { System.out.println("Could not close."); System.exit(-1); } } D. Rosaci Sistemi Distribuiti: I Processi 26 Codice del Server - 6 public static void main(String[] args){ SocketServer frame = new SocketServer(); frame.setTitle("Server Program"); WindowListener l = new WindowAdapter() { public void windowClosing(WindowEvent e) { System.exit(0); } }; frame.addWindowListener(l); frame.pack(); frame.setVisible(true); frame.listenSocket(); } }//fine classe SocketServer D. Rosaci Sistemi Distribuiti: I Processi 27 Server Multithreading • Per permettere la connessione contemporanea di più client, il server deve usare più thread D. Rosaci Sistemi Distribuiti: I Processi 28 Server Multithreading -1 import java.awt.Color; import java.awt.BorderLayout; import java.awt.event.*; import javax.swing.*; import java.io.*; import java.net.*; class ClientWorker implements Runnable { private Socket client; private JTextArea textArea; ClientWorker( Socket client, JTextArea textArea) { this.client = client; this.textArea = textArea; } D. Rosaci Sistemi Distribuiti: I Processi 29 Server Multithreading -2 public void run(){ String line; BufferedReader in = null; PrintWriter out = null; try{ in = new BufferedReader(new InputStreamReader(client.getInputStream())); out = new PrintWriter(client.getOutputStream(), true); } catch (IOException e) { System.out.println("in or out failed"); System.exit(-1); } while(true){ try{ line = in.readLine(); //Send data back to client out.println(line); textArea.append(line); } catch (IOException e) { System.out.println("Read failed"); System.exit(-1); } }}} D. Rosaci Sistemi Distribuiti: I Processi 30 Server Multithreading -3 class SocketThrdServer extends JFrame{ JLabel label = new JLabel("Text received over socket:"); JPanel panel; JTextArea textArea = new JTextArea(); ServerSocket server = null; SocketThrdServer(){ //Begin Constructor panel = new JPanel(); panel.setLayout(new BorderLayout()); panel.setBackground(Color.white); getContentPane().add(panel); panel.add("North", label); panel.add("Center", textArea); } //End Constructor D. Rosaci Sistemi Distribuiti: I Processi 31 Server Multithreading -4 public void listenSocket(){ try{ server = new ServerSocket(4444); } catch (IOException e) { System.out.println("Could not listen on port 4444"); System.exit(-1); } while(true){ ClientWorker w; try{ w = new ClientWorker(server.accept(), textArea); Thread t = new Thread(w); t.start(); } catch (IOException e) { System.out.println("Accept failed: 4444"); System.exit(-1); } }} D. Rosaci Sistemi Distribuiti: I Processi 32 Server Multithreading -5 protected void finalize(){ try{ server.close(); } catch (IOException e) { System.out.println("Could not close socket"); System.exit(-1); } } D. Rosaci Sistemi Distribuiti: I Processi 33 Server Multithreading -6 public static void main(String[] args){ SocketThrdServer frame = new SocketThrdServer(); frame.setTitle("Server Program"); WindowListener l = new WindowAdapter() { public void windowClosing(WindowEvent e) { System.exit(0); } }; frame.addWindowListener(l); frame.pack(); frame.setVisible(true); frame.listenSocket(); }} D. Rosaci Sistemi Distribuiti: I Processi 34 Paradigma ad Oggetti distribuiti • • • Le risorse di rete sono rappresentate da oggetti distribuiti: Per richiedere un servizio ad una risorsa di rete, un processo invoca uno dei metodi o operazioni messe a disposizione, passando al metodo i dati come parametri. Il metodo viene eseguito sull’ host remoto, e la risposta è inviata al processo richiedente come valore di ritorno. D. Rosaci Sistemi Distribuiti: I Processi 35 Chiamate di Metodi • Un processo in esecuzione su un host A chiama un metodo su un oggetto distribuito che risiede su un host B, passando allo stesso eventuali parametri • La chiamata del metodo invoca un’ azione che il metodo eseguirà sull’ host B. Il valore di ritorno, se c’è, verrà trasferito dall’ host B all’ host A • Un processo che fa uso di un oggetto distribuito viene detto processo client di quell’ oggetto, e i metodi dell’ oggetto sono chiamati metodi remoti (contrariamente ai metodi locali, o metodi appartenenti ad un oggetto locale) D. Rosaci Sistemi Distribuiti: I Processi 36 Architettura di un Sistema ad Oggetti Distribuiti D. Rosaci Sistemi Distribuiti: I Processi 37