La descarga está en progreso. Por favor, espere

La descarga está en progreso. Por favor, espere

Juan Camilo Jiménez Dorado Diciembre 2011.

Presentaciones similares


Presentación del tema: "Juan Camilo Jiménez Dorado Diciembre 2011."— Transcripción de la presentación:

1 Juan Camilo Jiménez Dorado Diciembre 2011

2 Instrucciones Estado Memoria de trabajo Información de planificación Ejecución de un programa compuesto por:

3 Unidad mínima de asignación de recursos: Proceso (Tarea).

4 Sub rutinas ejecutándose dentro de un proceso. Se usan cuando: El hilo principal no es suficientemente veloz. Se necesita procesamiento asincrónico. Se necesita procesamiento en paralelo. Se va a realizar procesamiento en batch. Se van a recibir peticiones simultaneas. (como lo hacen ASP.NET, WCF, Web Services, or Remoting)

5 Unidad mínima de expedición de recursos: Hilo. (comparten recursos)

6 Estado Descripción RunningEl subproceso se ha iniciado, no está bloqueado y no existe una excepción ThreadAbortException pendiente.ThreadAbortException StopRequestedSe ha solicitado que el subproceso se detenga. Esto último sólo se refiere al uso interno. SuspendRequestedEl subproceso se ha marcado para suspensión. BackgroundEl subproceso está ejecutándose como subproceso en segundo plano, por oposición a un subproceso en primer plano. Para controlar este estado, hay que establecer la propiedad Thread.IsBackground.Thread.IsBackground UnstartedNo se ha invocado al método Thread.Start en el subproceso.Thread.Start StoppedEl subproceso se ha detenido. WaitSleepJoinSubproceso bloqueado. Este podría ser el resultado de llamar a Thread.Sleep o Thread.Join, de solicitar un bloqueo (por ejemplo, llamando a Monitor.Enter o Monitor.Wait) o de esperar en un objeto de sincronización de subprocesos como ManualResetEvent.Thread.SleepThread.JoinMonitor.EnterMonitor.WaitManualResetEvent SuspendedEl subproceso se ha suspendido. AbortRequestedSe ha invocado al método Thread.Abort en el subproceso, pero el subproceso aún no ha recibido la excepciónSystem.Threading.ThreadAbortException pendiente que intentará finalizarlo.Thread.AbortSystem.Threading.ThreadAbortException AbortedEl estado del subproceso incluye AbortRequested y el subproceso está ahora inactivo, pero su estado no ha cambiado todavía aStopped.

7 AcciónThreadState Se crea un subproceso dentro de Common Language Runtime.Unstarted Otro subproceso llama al método Start del subproceso.StartUnstarted El subproceso comienza a ejecutarse.Running El subproceso llama a Sleep.SleepWaitSleepJoin El subproceso llama a Wait o realiza alguna otra llamada de bloqueo.WaitWaitSleepJoin El subproceso llama a Join en otro subproceso.JoinWaitSleepJoin Common Language Runtime marca el subproceso de suspensión, por ejemplo, para realizar la recolección de elementos no utilizados. SuspendRequested Subproceso suspendido.Suspended El subproceso se reanuda después de que haya sido suspendido.Running Otro subproceso llama a Thread.Abort en el subproceso.Thread.AbortAbortRequested Subproceso finalizado.Stopped El propio subproceso u otro ha establecido la propiedad Thread.IsBackground del subproceso en true.Thread.IsBackground Background

8

9 Se tarda mucho menos tiempo en crear un hilo nuevo en un proceso existente que en crear un proceso. Se tarda mucho menos en terminar un hilo que un proceso. Se tarda mucho menos tiempo en cambiar entre dos hilos de un mismo proceso. Los hilos aumentan la eficiencia de la comunicación entre programas en ejecución.

10 Incrementan la complejidad de la aplicación. No siempre a mayor número de hilos mayor performance. El número incorrecto de hilos puede perjudicar el rendimiento. En operaciones de escritura de disco, muchos hilos perjudican el porformance.

11 Punto de entrada de un proceso. Puede dar inicio a los demás hilos

12 class Program { static void Main() { Thread t = new Thread (WriteY); // Crear un nuevo hilo secundario t.Start(); // Iniciar hilo secundario // Imprimir X en el hilo principal for (int i = 0; i < 1000; i++) Console.Write ("x"); } static void WriteY() { // Imprimir Y en el hilo secundario for (int i = 0; i < 1000; i++) Console.Write ("y"); }

13 public static void main() { new Thread(Go).Start(); // Llama GoShare() en un nuevo hiloo Go(); // Llama GoShare() en el hilo principal } static void Go() { // Imprime ? 5 veces cada que lo llamen for (int cycles = 0; cycles < 5; cycles++) Console.Write('?'); } bool done; public static void main() { ShareSameInstance tt = new ShareSameInstance(); // Crea una instancia com ú n de la clase program new Thread(tt.Go).Start(); tt.Go(); } // Go() pasa a ser un m é todo de instancia void Go() { if (!done) { done = true; Console.WriteLine("Done"); } } Nota: Tambien se pueden datos a través de variables estáticas

14 Espera hasta que un hilo termine para continuar con la ejecución. static void main() { Thread t = new Thread(Go); t.Start(); t.Join(); Console.WriteLine("El hilo ha terminado!"); } static void Go() { for (int i = 0; i < 1000; i++) Console.Write("y"); } Se puede usar un TimeSpan para elegir un time out t.Join(TimeSpan.FromSeconds(2));

15 Nota: Mientras se usa Sleep o Join, el hilo está bloqueado y no consume recursos de CPU Suspende un hilo por un tiempo determinado Thread.Sleep(TimeSpan.FromMinutes(1));

16 Interrupt desbloquea hilos previamente bloqueados, mientras que abort los interrupe así no estén bloqueados. Interrupt espera hasta el próximo bloqueo del hilo para ejecutar las demás instrucciones. Nota: la operación abort es insegura en la mayoría de escenarios, por ejemplo, cuando se está escribiendo en disco. public static void main() { Thread t = new Thread(Go); t.Start(); t.Abort(); } static void Go() { while (true) { // Imprime X hasta que se cancela Console.Write('X'); } public static void main() { var cancelSource = new CancellationTokenSource(); new Thread(() => Go(cancelSource.Token)).Start(); cancelSource.Cancel(); } static void Go(CancellationToken cancelToken) { cancelToken.ThrowIfCancellationRequested(); // Imprime X hasta que se cancela for (int cycles = 0; cycles < 5; cycles++) Console.Write('X'); } UnSafeSafe

17 Usando el formulario frmThreadingStates en el proyecto Threading2, implemente cada una de las operaciones básicas de un hilo usando cada botón de la interfaz gráfica y mostrando los valores asignando texto a la variable global text.

18 public static void main() { Thread.CurrentThread.Name = "main"; Thread worker = new Thread(Go); worker.Name = "worker"; worker.Start(); Go(); } static void Go() { Console.WriteLine("Este es el hilo " + Thread.CurrentThread.Name); } Los hilos se pueden nombrar para identificarlos en tiempo de ejecución. De esta manera se pueden ver en el Threads Window.

19 public static void main() { Thread t = new Thread(() => Print("Hola mundo!")); t.Start(); } static void Print(string message) { Console.WriteLine(message); } Usando expresiones Lambda: public static void main() { Thread tt = new Thread(new ParameterizedThreadStart(PrintB)); tt.Start("Hola mundo B!"); } static void PrintB(object message) { Console.WriteLine(message); } Usando ParameterizedThreadStart:

20 Los hilos tipo foreground mantienen la aplicación viva mientras al menos uno de ellos esté corriendo. public static void main() { //Los hilos son foreground por defecto Thread worker = new Thread(() => Console.ReadLine()); worker.Start(); //El hilo principal termina pero la aplicaci ó n porque el hilo worker es foreground por defecto } Una vez finalizan todos los hilos foreground, todos los hilos background son matados súbitamente. public static void main() { Thread worker = new Thread(() => Console.ReadLine()); worker.IsBackground = true; worker.Start(); //El hilo principal termina y mata al hilo secundario inmediatamente por ser background }

21 enum ThreadPriority { Lowest, BelowNormal, Normal, AboveNormal, Highest } Determina cual es su tiempo de ejecución relativo a otros hilos por parte del sistema operativo relativo. Nota: La prioridad de un hilo se debe escoger cuidadosamente para no sobrecargar la CPU. using (Process p = Process.GetCurrentProcess()) p.PriorityClass = ProcessPriorityClass.High; También es posible alterar la prioridad de los procesos, especialmente para trabajo en tiempo real worker.Priority = ThreadPriority.Highest;

22 Las excepciones no tienen sentido en el ámbito de la función que inicia el hilo: public static void main() { try { new Thread(Go).Start(); } catch (System.Exception ex) { // nunca llega aqui! Console.WriteLine("Exception!"); } Las excepciones se deben controlar en la función del hilo: static void Go() { try { throw null; } catch (System.Exception ex) { // Captura la excepci ó n Console.WriteLine("Exception en el Go!"); }

23 private static Thread[] TArray; public static void main() { ThreadArray ta; //declaramos un arreglo de 5 hilos TArray = new Thread[5]; for (int i = 0; i < TArray.Length; i++) { ta = new ThreadArray(); TArray[i] = new Thread(new ParameterizedThreadStart(ta.Go)); } //iniciamos los 5 hilos pasando como parametro el n ú mero de cada hilo para que imprima for (int i = 0; i < TArray.Length; i++) { TArray[i].Start(i+1); } //Iniciamos un hilo con prioridad alta imprimiendo x ta = new ThreadArray(); Thread t = new Thread(() => ta.Go("x")); t.Start(); } void Go(object num) { for (int i = 0; i < 100; i++) { Console.Write(num.ToString()); }

24 Implemente una rutina con un arreglo de hilos que imprima los números del 1 al 10, 100 veces cada uno y al mismo tiempo inicie otro hilo que imprima su nombre 200 veces con mayor prioridad que los números. Una vez impreso su nombre 200 veces, generar una excepción que en su catch aborte todos los hilos de los números.

25 Coordinación de las acciones de los hilos. Dividida en 4 tipos: Bloqueo simple: Sleep, Join, Task.Wait. Locking: Lock, Mutex, SpinLock Nonblocking: Semaphores Signaling:

26 Cuando dos hilos intentan acceder al mismo recurso al mismo tiempo es thread unsafe. static bool done; // Los campos est á ticos se comparten en todos los hilos public static void main() { new Thread(Go).Start(); Go(); } static void Go() { //mientras un hilo est á evaluando el if el otro puede estar haciendo el writeline antes de poner done=true if (!done) { Console.WriteLine("Done"); done = true; } }

27 static DateTime flag; public static void main() { flag = DateTime.Now.AddSeconds(-40); Thread t = new Thread(Go); t.Start(); t.Join(); Console.Write("El hilo ha terminado!"); } static void Go() { while (flag < DateTime.Now) { Console.Write("y"); } El spinning puede servir para poner a los hilos a esperar pero puede acarrear problemas de concurrencia.

28 static bool done; static readonly object locker = new object(); public static void main() { new Thread(Go).Start(); Go(); } static void Go() { lock (locker) { if (!done) { Console.WriteLine("Done"); done = true; } } Asegura que solo un hilo acceda a cierta porción de código Cuando un hilo se enfrenta a un lock, este se pone en estado blocked (waiting) y espera hasta que se desbloquee la porción de código. Nota: La regla de oro del locking es usarlo en cualquier operación de asignación de variables.

29 class ThreadUnsafe { static int _val1 = 1, _val2 = 1; public static void main() { Thread t = new Thread(Go); t.Start(); } static void Go() { if (_val2 != 0) Console.WriteLine (_val1 / _val2); _val2 = 0; } Considere la siguiente clase: Identifique el error que se produciría si otro hilo llamara a la función Go(). Implemente otro hilo llamando a la función Go para reproducir el error. Resuelva el error usando los conocimientos adquiridos.

30 Es como una discoteca, tiene una capacidad limitada y una vez se llena no puede entrar nadie hasta que salga otra persona. El Lock() y el Mutex() son como semaphores con capacidad de 1. Los semaphores son muy útiles para limitar el número de hilos que acceden a cierta función y así controlar la concurrencia. Nota: contrario a Lock() y Mutex(), los semaphores no tienen dueño, es decir, cualquier hilo los puede liberar. static SemaphoreSlim _sem = new SemaphoreSlim(3); // capacidad 3 public static void main() { //5 hilos tratando de entrar for (int i = 1; i <= 5; i++) new Thread(Enter).Start(i); } static void Enter(object id) { Console.WriteLine(id + " quiere entrar"); _sem.Wait(); // s ó lo 3 hilos pueden estar aqui al mismo tiempo Console.WriteLine(id + " est á adentro!"); Thread.Sleep(1000 * (int)id); Console.WriteLine(id + " est á saliendo"); _sem.Release(); }

31 El signaling se apoya en los Event Wait Handles para lograr que un hilo espere confirmación de otro hilo para realizar acciones específicas. A continuación se muestran los diversos tipos de Event Wait Handles soportados por.NET: ConstructorPropositoCross-process? AutoResetEventPermite a un hilo desbloquearse apenas reciba una señal de otro hilo. Si ManualResetEventPermite a un hilo desbloquearse indefinidamente cuando recibe una señal de otro hilo (hasta que ocurra un reset). Si ManualResetEventSlimPermite a un hilo desbloquearse indefinidamente cuando recibe una señal de otro hilo (hasta que ocurra un reset). - CountdownEventPermite a un hilo desbloquearse cuando recibe un número determinado de señales. - BarrierImplementa una barrera de ejecución de hilo - Wait and PulsePermite a un hilo desbloquearse cuando se cumpla cierta condición.

32 Igual que cuando un usuario del metro mete su ticket en el torniquete, este se desbloquea automaticamente para dejar meter otro ticket cuando el usuario pasa. Solo un ticket por usuario. static EventWaitHandle _waitHandle = new EventWaitHandle(false, EventResetMode.AutoReset); public static void main() { new Thread(Waiter).Start(); //Pausa el hilo principal por 1 segundo Thread.Sleep(1000); // Env í a la se ñ al a los waiter para despertarlos _waitHandle.Set(); } static void Waiter() { Console.WriteLine("Esperando..."); // espera por la notificación del hilo principal, que puede no llegarle porque esa señal la usa otro Waiter _waitHandle.WaitOne(); Console.WriteLine("Notificado!"); }

33 Funciona como una puerta ordinaria, cuando la puerta se abre todos los hilos pasan y cuando se cierra ya no pasan mas hilos. Al usar Set() se abre la puerta, permitiendo a todos los hilos en espera continuar. Al usar Reset() se cierra la puerta. static EventWaitHandle _waitHandle = new System.Threading.ManualResetEvent(false); public static void main() { new Thread(Waiter).Start(); new Thread(Waiter2).Start(); //Pausa el hilo principal por 1 segundo Thread.Sleep(1000); //Env í a la se ñ al a los dos waiter para despertarlos _waitHandle.Set(); } static void Waiter() { Console.WriteLine("Esperando..."); //esperar por la notificaci ó n del hilo principal _waitHandle.WaitOne(); Console.WriteLine("Notificado 1!"); } static void Waiter2() { Console.WriteLine("Esperando..."); //esperar por la notificaci ó n del hilo principal _waitHandle.WaitOne(); Console.WriteLine("Notificado 2!"); }

34 Espera un número determinado de señales para desbloquear. static CountdownEvent _countdown = new CountdownEvent(3); public static void main() { new Thread(SaySomething).Start("Hilo 1"); new Thread(SaySomething).Start("Hilo 2"); new Thread(SaySomething).Start("Hilo 3"); //Bloquea hasta que la se ñ al haya llegado 3 veces _countdown.Wait(); Console.WriteLine("Todos los hilos han terminado de comunicarse!"); } static void SaySomething(object thing) { Thread.Sleep(1000); Console.WriteLine(thing); _countdown.Signal(); }

35 Es posible que la comunicación entre dos hilos se haga en doble vía usando dos Event Wait Handle, de esta manera se pueden resolver escenarios dónde un hilo debe notificar mas de una vez al otro. static EventWaitHandle _ready = new EventWaitHandle(false, EventResetMode.AutoReset); static EventWaitHandle _go = new EventWaitHandle(false, EventResetMode.AutoReset); static readonly object _locker = new object(); static string _message; public static void main() { new Thread(Work).Start(); _ready.WaitOne(); //Espera hasta que el worker est é listo lock (_locker) _message = "ooo"; _go.Set(); // Le dice al worker que siga desde el hilo principal _ready.WaitOne(); lock (_locker) _message = "ahhh"; // Env í a otro mensaje al worker desde el hilo principal _go.Set(); _ready.WaitOne(); // Le dice al worker que se salga poniendo la variable _message en nulo lock (_locker) _message = null; _go.Set(); } static void Work() { while (true) { _ready.Set(); // Indica al hilo principal que ya est á listo _go.WaitOne(); // Espera se ñ al del hilo principal para seguir lock (_locker) { if (_message == null) return; //Se sale de este hilo Console.WriteLine(_message); }

36 Aparte de los métodos Set(), WaitOne() y Reset(), la clase WaitHandle tiene los siguiente métodos estáticos: WaitAny: espera por cualquiera de los WaitHandle especificados. WaitAll: espera todos los WaitHandle especificados. SignalAndWait: llama set() en el primer WaitHandle especificado y llama WaitOne() en el segundo. Muy útil para coordinar señales entre 2 hilos.

37 El organismo de transito de la ciudad tiene una capacidad para 20 usuarios en su sala de espera, por lo que si llegan mas usuarios tienen que esperar afuera hasta que algun usuario sea atendido. Al llegar a la portería del tránsito, los usuarios son atendidos por un funcionario que les recibe los papeles para iniciar su tramite y los deja pasar en caso de haber espacio en la sala de espera o cuando lo haya. Una vez adentro de la sala de espera, la finalización del tramite dura 3 segundos antes de salir de la sala. Es necesario conocer cuando se temrinen de atender las primeras 40 personas. Represente la situación anterior en una rutina de.NET usando los conocimientos adquiridos en semaphores y signaling.

38 g.pdf g.pdf C3%B3n C3%B3n


Descargar ppt "Juan Camilo Jiménez Dorado Diciembre 2011."

Presentaciones similares


Anuncios Google