using System; using System.Threading; namespace Recetas.CSharp.Cap04.R0410 { public sealed class SincronizacionConsola { // Determina el estado de ejecución de un thread: private static bool terminarThread = false; // Muestra mensajes de información acerca del estado // de ejecución de un thread: private static void Rastrear(string mensaje) { Console.WriteLine ("[{0,3}] - {1} : {2}", Thread.CurrentThread.ManagedThreadId, DateTime.Now.ToString("HH:mm:ss.ffff"), mensaje ); } // Método a encapsular por diferentes threads y que // contiene una región crítica protegida por un // objeto Semaphore: private static void MostrarMensajeEnConsola() { // Se apropia de un instancia Semaphore con nombre // 'EjemploSemaphore': using (Semaphore semaforo = Semaphore.OpenExisting ("EjemploSemaphore")) { Rastrear("Inicio ejecución de thread."); while (!terminarThread) { // Apoderamiento del semaforo: semaforo.WaitOne(); Rastrear("Apoderamiento del Semaphore."); Thread.Sleep(1000); Rastrear ("Liberación del Semaphore."); semaforo.Release(); // Pausa para dar la oportunidad de que otro // thread se apodere del semaforo: Thread.Sleep (100); } Rastrear ("A punto de finalizar un thread."); } } public static void Main() { Console.Title = "Demostración uso de Sincronización con Semaphore"; Console.WriteLine (); // Creación de una instancia de Semaphore llamada `EjemploSemaphore`: using (Semaphore semaforo = new Semaphore (2, 2, "EjemploSemaphore")) { Rastrear ("Inicio de ejecución de threads. Presione Enter para finalizar."); // Creación de 3 threads: Thread t1 = new Thread (MostrarMensajeEnConsola); Thread t2 = new Thread (MostrarMensajeEnConsola); Thread t3 = new Thread (MostrarMensajeEnConsola); t1.Start(); t2.Start(); t3.Start(); // Para finalizar se debe presionar Enter: Console.ReadLine (); // Finaliza los threads asociados con el método `MostrarMensajeEnConsola`, // y espera a que se completan antes de deshechar la instancia Semaphore: terminarThread = true; t1.Join(5000); t2.Join(5000); t3.Join(5000); } } } }