Sincronización de hilos

Hola!

Hoy voy a hacer un artículo sobre sincronización de hilos. He visto alguna que otra vez una forma poco correcta de hacer que un hilo padre espere a que su hijo haya terminado (como quedarse en un bucle con un Sleep y comprobar periódicamente si el hilo hijo está vivo), así que voy a explicar una forma muy sencilla de coordinar los hilos.

Como ejemplo podemos usar un servicio de Windows, ya que en estos servicios, la creación de un hilo suele ser casi imprescindible, porque lo normal es que cuando el servicio arranca nosotros generalmente querremos que el servicio se quede activo, pero debemos salir del método OnStart del servicio tan pronto como sea posible para evitar un Timeout en el arranque.

Además, sería interesante que cuando paramos el servicio, en el método OnStop del servicio, el hilo principal espere a que el hilo hijo termine aquello que esté haciendo en ese momento, para no cortar alguna operación que se pueda estar realizando cuando se quiere parar el servicio.

Para conseguir esto, en nuestra clase del servicio podemos declarar un miembro que contenga un WaitHandle en el que almacenaremos si nuestro hilo hijo ha terminado su ejecución. Este WaitHandle es el que usará el hilo padre para esperar al hilo hijo.

Una breve descripción de lo que haremos en el servicio será lo siguiente:

  • Al arrancar el servicio, crearemos un hilo nuevo en el ThreadPool, usando el método QueueUserWorkItem, al que le pasaremos el WaitHandle que hemos definido en la clase. Como WaitHandle es una clase abstracta, podemos usar (por ejemplo) un AutoResetEvent.
  • Al parar el servicio, esperaremos a que el hilo hijo que creamos al arrancar el servicio termine su ejecución. Para ello usaremos el método estático WaitAll de la clase WaitHandle, pasándole como argumento el objeto estático de tipo WaitHandle que usamos al arrancar el servicio.
  • En el método que ejecuta el hilo hijo debemos:
    • Recibir el objeto WaitHandle (AutoResetEvent) que nos pasa el hilo que nos ha creado, y almacenarlo.
    • Agrupar la ejecución del servidor en un bloque try { … } finally { … } (se puede-debe poner un catch), y en el finally deberemos notificar que hemos terminado la ejecución, llamando al método Set del objeto AutoResetEvent que hemos recibido, así nos aseguramos de que notificaremos que hemos terminado la ejecución del hilo hijo al hilo padre.

Bueno, pues ésta es la idea básicamente.

Saludos! 

Un comentario sobre “Sincronización de hilos”

  1. Hola, esta bastante bien la logica, pero soy novato en esto y estoy tratando de reiniciar un hilo que esta detenido y no puedo hacerlo. jejeje…

    No se si sea correcto pero como puedo reniciarlo, o si no se su pudiese como elimino ese hilo o solo por el hecho de estar detenido no importaria crear nuevo hilo que cumpla lo mismo que el hacia cuando esta corriendo o iniciado

    atte. rmarcelo

Deja un comentario

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *