Está en la página 1de 7

Servidores Multiproceso

PID=1 atiende A

Tema 2: Aplicaciones Multihilo, Cliente Servidor

PID=2 atiende B
t=1. A puja
Fork() Fork()

PID=3 atiende ..

Web Server
process_new_connection() Web_Server_Main () t=1. B puja { for (;;) { new_connection = accept (i, NULL, NULL); Process_new_connection(); } } ap_scoreboard_image>parent[slot].pid = pid; return 0; }
2

{ if ((pid = fork()) == 0) { child_main(slot);

Multiples Clientes Concurrente

Porqu Multitarea (multiples hilos o procesos)


Para poder cancelar tareas independientemente. Algunos problemas son intrinsecamente paralelos: Simuladores, Servidores, Recolectores,.. Para beneficiarse de hardware con multiples procesadores.

Creacin de procesos
int pid; if (pid= fork()) == -1) perror(error); else if (pid == 0) /*cdigo del proc. hijo*/ else /* cdigo del proc. padre */ El ncleo del SO. con la llamada fork(): 1. Busca una entrada libre en la tabla de procesos y reservar memoria. 2. Asigna un identificador nico al pro. hijo. 3. Realiza las copias del contexto del proc. padre para el proc. hijo. 4. Copia las tablas de control de ficheros del proc. padre para el proc. hijo. 5. Retorna al proceso padre el pid del hijo y al hijo el valor cero. P_hijo
4

P_padre
3

Procesos pesados vs. ligeros (I)


Proceso pesado = proceso unix o win32 o .. Proceso ligero = hilo (thread).
Un proceso pesado en un sistema operativo se representa por su cdigo, datos en memoria, y el estado de los registros de la mquina PCB. Los hilos de un mismo proceso pesado COMPARTEN el espacio de memoria.

Procesos pesados vs. ligeros (II)


La comparticin de una CPU entre multiples tareas de tal manera que se minimice el tiempo requerido para cambiar entre tareas. Esto se consigue compatiendo el mximo posible del entorno de ejecucin del programa entre las diferente tareas de tal manera que muy poca informacin de estado se necesita guardar y cargar cuando se cambie de tareas. Los hilo siempre existen dentro de un proceso pesado, lo necesitan. Para poder soportar procesos ligeros (hilos de control), se dispone de mltiples pilas, una por cada hilo creado.
5 6

Implementaciones de Hilos
A parent process may spawn child processes. parent process A process may spawn child threads a process main thread child thread 1

Hilos en Java (I)


Una clase Thread gestiona un nico hilo secuencial de control. Los hilos pueden crearse y destruirse dinmicamente.
La clase Thread ejecuta instrucciones incluidas en su mtodo run(). El cdigo real ejecutado depende de la implementacin dada para el mtodo run() en una clase derivada.

Thread
child processes child thread 2

run()

Los hilo siempre existen dentro de un proceso pesado, lo necesitan. Programas que implementan la gestin de hilos, p.ej. Java Virtual Machine. Las aplicaciones multihilo se ejecutan dentro del proceso del programa. Tambin existen sistemas operativos que implementan en su kernel la gestin de hilos: Windows NT, y muchas variantes de Unix. en este caso los hilos tambin estn dentro de un proceso.
7

MyThread run()

class MyThread extends Thread { public void run() { //...... } }

Ejemplo Hilos en Java (I)


import SomeThread ; public class RunThreads { public static void main (String[] args) { SomeThread p1 = new SomeThread (1); p1.start (); SomeThread p2 = new SomeThread (2); p2.start (); SomeThread p3 = new SomeThread (3); p3.start (); } }// end class RunThreads public class SomeThread extends Thread { int myID ; SomeThread (int id) { this.myID = id; } public void run( ) { int i; for (i = 1; i < 11; i++) System.out.println ("Thread"+ myID + ": " + i); } } //end class SomeThread

Ejecucin de Ejemplo
Salida Ejecucin RunThreads: Thread3: 1 Thread3: 2 Thread3: 3 Thread1: 1 Thread1: 2 Thread1: 3 Thread1: 4 Thread1: 5 Thread1: 6 Totalmente Thread1: 7 Thread1: 8 Concurrente Thread1: 9 Thread1: 10 (aunque la Thread3: 4 Thread3: 5 salida de linux Thread3: 6 vs. Window Thread3: 7 Thread3: 8 suele diferir) Thread3: 9 Thread3: 10 Thread2: 1 Thread2: 2 Thread2: 3 Thread2: 4 Thread2: 5 Thread2: 6 Thread2: 7 Thread2: 8 Salida Ejecucin RunThreads con sleep(10): Thread1: 1 Thread2: 1 Thread3: 1 Thread1: 2 Thread2: 2 Thread3: 2 Thread2: 3 Thread1: 3 Cada 10 seg. los 3 Thread3: 3 hilos escriben Thread2: 4 concurrentemente. Thread1: 4 Thread3: 4 Thread2: 5 Thread3: 5 Thread1: 5 Thread2: 6 Thread3: 6 Thread1: 6 Thread2: 7 Thread3: 7 Thread1: 7 Thread2: 8 10 Thread3: 8

Una clase Thread tiene que implementar el metodo run(), Una clase Thread se inicia llamando al metodo start().
9

Hilos en Java (II)


Se puede implementar el mtodo run() directamente desde el interfaz Runnable, y asociarle un Thread para su ejecucin. Este manera de usar hilos es ms verstil, ya que puede derivarse de otras clases. target Runnable run() Thread Public interface Runnable { public abstract void run(); }

Ejemplo Hilos en Java (II)


public class RunThreads2 { public static void main (String[] args) { Thread p1 = new Thread(new SomeThread2(1)); p1.start(); Thread p2 = new Thread(new SomeThread2(2)); p2.start(); Thread p3 = new Thread(new SomeThread2(3)); p3.start(); } } class SomeThread2 implements Runnable { int myID; SomeThread2(int id) { this.myID = id; } public void run() { int i; for (i = 1; i < 11; i++) System.out.println ("Thread"+myID + ": " + i); } } //end class SomeThread

MyRun run()

class MyRun implements Runnable { public void run() { // ..... } }


11

Un constructor de clase Thread: public Thread(Runnable target)


12

Ciclo de vida de un hilo en Java

hilo finalizado? (I)


public class RunThreads3 { public static void main (String[] args) { int originalThreadCount = Thread.activeCount( ); for (int i=0; i<10; i++) { Thread p = new Thread(new SomeThread3()); p.start(); } while (Thread.activeCount() > originalThreadCount ){ // loop until all child threads have exited. }
// todos los hilos finalizados, continua.

sleep(),join() start()

start() comienza el hilo, siempre llama a run() sleep(x) duerme el hilo un tiempo. join() espera a que otro hilo finalice.
13

} }
14

hilo finalizado?(II): isAlive()


// Create and start a thread Thread thread = new MyThread(); thread.start(); // Check if the thread has finished // in a non-blocking way while (thread.isAlive()) { // Thread has not finished } else {
// otro hilo finalizado, continua.

hilo finalizado? (III): join()


// Create and start a thread Thread thread = new MyThread(); thread.start();

// Wait indefinitely for the thread to finish try { Bloqueante thread.join();


// otro hilo finalizado, continua.

} }

. } catch (InterruptedException e) { // Thread was interrupted

15

16

Race Condition en Threads


class SomeThread3 implements Runnable { static int count=0;

Syncronize en Threads
class SomeThread3 implements Runnable { static int count=0;

Instruction execution order:


SomeThread3() { super(); } public void run() { update(); } static public void update( ){ int myCount = count; int second = (int)(Math.random( ) * 500); try { Thread.sleep(second); } catch (InterruptedException e) { } myCount++; count = myCount; System.out.println("count= "+count); } }
17

Instruction execution order:


SomeThread3() { super(); } public void run() { update(); } static public synchronized void update( ){ int myCount = count; int second = (int)(Math.random( ) * 500); try { Thread.sleep(second); } catch (InterruptedException e) { } myCount++; count = myCount; System.out.println("count="+count); } }
18

Hilo 1 llama update, Hilo 2 llama update, .

Hilo 1 llama update,


Time Hilo 1: count = 1 Hilo 2: count = 2 Hilo 3 llama update, Hilo 3: count = 3 Hilo 4 llama update, Hilo 4: count = 4 . .

Hilo 2 llama update,

Hilo 1: count = 1
Time Hilo 2: count = 2 Hilo 3: count = 2 Hilo 4: count = 1 Hilo 5: count = 1 . . No DESEADO

Multiples Clientes Concurrentes

Paradigma Cliente Servidor


Multiples Cliente Un Servidor
Servidor sin conexin:
Usa IPC sin conexin (p.ej., datagram socket) Las sesiones con clientes concurrentes se pueden intercalar.

t=1. A puja 50E por BMW

Hilo 1 atiende A Hilo 2 atiende B H1 H2 Hilo 3 atiende C H3

Servidor con conexin:


Usa IPC con conexin (p.ej. stream-mode socket ) Sesiones con clientes concurrentes solo pueden ser secuenciales. Concurrencia necesita servidor multitarea.

t=1. B puja 60E por BMW eBay Server

t=1. C Lee Puja Actual de BMW.


19 20

Sesiones de clientes concurrentes con servidor sin conexin


EchoServer1 message echo message echo message echo message echo message echo client 1 client2

Servidor con Sockets sin conexin


public class EchoServer1 { public static void main(String[] args) { // instantiates a datagram socket for both sending and receiving data MyServerDatagramSocket mySocket = new MyServerDatagramSocket(serverPort); while (true) { // forever loop DatagramMessage request = mySocket.receiveMessageAndSender(); String msg = request.getMessage( ); mySocket.sendMessage(request.getAddress( ), request.getPort( ), msg); } //end while }
public class MyServerDatagramSocket extends DatagramSocket { MyServerDatagramSocket(int portNo) throws SocketException{ super(portNo); } public void sendMessage(InetAddress receiverHost, int receiverPort, string message); public String receiveMessage( ); public DatagramMessage receiveMessageAndSender( ); } //end class

Bucle Bucle = Sesin Servidor cliente.

21

22

Servidores Iterativos (socket con conexin) Sesiones cliente consecutivas.


EchoServer2 Message 1a Echo 1a Message 2a Message 1b Echo 1b Message . Echo 2a Message 2b Echo 2b Client 1 Client 2

Servidor Iterativo (socket con conexin)


public class EchoServer2 { public static void main(String[] args) { ServerSocket myConnectionSocket = new ServerSocket(serverPort); while (true) { // forever loop MyStreamSocket myDataSocket = new MyStreamSocket (myConnectionSocket.accept( )); boolean done = false; while (!done) { message = myDataSocket.receiveMessage( ); if ((message.trim()).equals (endMessage)) { myDataSocket.close( ); done = true; } //end if else { myDataSocket.sendMessage(message); } //end else } //end while !done } //end while forever
23

Bucle servidor.

Bucle sesin cliente.

24

Servidor concurrente: sesiones concurrentes


EchoServer3 message echo message echo message echo client 1 message echo message echo client2

Sequence diagram EchoServer3


EchoServer3 EchoClient EchoServer3 thread 1 EchoServer3 thread 2 1 EchoClient2

accept

accept

25

26

Servidor MultiHilo
import java.io.*; import java.net.*; public class EchoServer3 { public static void main(String[] args) { int serverPort = 7; // default port String message; try { // instantiates a stream socket for accepting // connections ServerSocket myConnectionSocket = new ServerSocket(serverPort); while (true) { // forever loop // wait to accept a connection MyStreamSocket myDataSocket = new MyStreamSocket (myConnectionSocket.accept( )); // Start a thread to handle this client's sesson Thread theThread = new Thread(new EchoServerThread(myDataSocket)); theThread.start(); } //end while forever } // end try catch (Exception ex) { Cliente ex.printStackTrace( ); } // end catch } //end main } // end class

Hilo Atiende un Cliente


Por cada cliente: Nuevo thread, Start thread.
Hilo2 Hilo1
Server Thread
new Thread() Thread.start() import java.io.*; class EchoServerThread implements Runnable { static final String endMessage = "."; MyStreamSocket myDataSocket; EchoServerThread(MyStreamSocket myDataSocket) { this.myDataSocket = myDataSocket; } public void run( ) { boolean done = false; String message; try { while (!done) { message = myDataSocket.receiveMessage( ); if ((message.trim()).equals (endMessage)){ myDataSocket.close( ); done = true; } //end if else { myDataSocket.sendMessage(message); } //end else } //end while !done }// end try Cliente catch (Exception ex) { System.out.println("Exception " + ex); } // end catch } //end run } //end class

Constructor recibe un DataSocket. El cdigo en run() se ejecuta para cada peticin.


Hilo2 Hilo1
run()

ServerThread

Server JVM PID3


27

Server JVM PID3


28

También podría gustarte