using System; using System.Threading; namespace Recetas.CSharp.Cap04.R0409 { public sealed class UsoSincronizacionMutex { // Crea una instancia de la clase `Mutex`; además // de un número de iteraciones por cada thread y la // cantidad de threads a crear: private static Mutex mutex = new Mutex(); private const int numeroIteraciones = 1; private const int numeroThreads = 3; // Punto de entrada a la aplicación: public static void Main() { Console.Title = "Acceso a Recursos Compartidos con Mutex"; Console.WriteLine (); // Crea los 3 threads, encapsula el método `Procesar`, // les asigna un identificador (alfanumérico), e // inicia cada thread: for (int i = 1; i <= numeroThreads; ++i) { Thread t = new Thread (new ThreadStart (Proceso)); t.Name = String.Format ("Thread No. {0}", i.ToString()); t.Start(); } } // Método encapsulado por cada thread: private static void Proceso() { for (int i = 1; i <= numeroIteraciones; ++i) { AccederRecursoCompartido(); } } // Método para el acceso de recursos compartidos. // Debe ser sincronizado: private static void AccederRecursoCompartido() { // Controla el acceso acceso seguro al recurso compartido. // Sólo se accede cuando el recurso está disponible: Console.WriteLine ("{0} está solicitando al acceso al recurso.", Thread.CurrentThread.Name ); if (mutex.WaitOne (1000)) { Console.WriteLine ("El thread `{0}` ha accedido al recurso compartido.", Thread.CurrentThread.Name ); // Especificación de los recursos que deben sincronizarse... // Simula la ejecución de una tarea que toma tiempo: Thread.Sleep (5000); Console.WriteLine ("El thread `{0}' está próximo a terminar.", Thread.CurrentThread.Name ); // Liberación del mutex: mutex.ReleaseMutex(); Console.WriteLine ("El thread `{0}` ha liberado el mutex.", Thread.CurrentThread.Name ); } else { Console.WriteLine ("El thread `{0}` no tendrá acceso al recurso compartido.", Thread.CurrentThread.Name ); } } } }