Índice
0. Introducción1. Problema
2. Solución
3. Discusión de la Solución
4. Práctica: Código C#
5. Conclusiones
6. Glosario
7. Literatura & Enlaces
0. Introducción
En esta séptima receta mulithreading en C# haremos algo muy interesante y es sincronizar múltiples threads dentro de un proceso que implementa lógica iterativa (ciclos, o loops) hasta que todos los threads hayan llegado a un punto concreto. Destacaremos otras importantes utilidades de este tipo de sincronización. El ejemplo que se presentará consistirá en la sincronización de una banda musical integrada por un guitarrista y un vocalista que deben estar sincronizados para que su interacción tenga sentido y ritmo.
1. Problema
Requerimos implementar lógica de sincronización que permita controlar y generar una señal de registro una vez que el flujo de ejecución de dos o más threads alcancen un determinado punto dentro del proceso.
2. Solución
La librería común de .NET ofrece la clase Barrier para la sincronización y cooperación de múltiples threads dentro de un proceso basado en fases/etapas.
3. Discusión de la Solución
La clase Barrier [2] (namespace System.Threading) permite que múltiples threads se ejecuten en paralelo para cooperar en cálculos, iteraciones, etc., dentro de un proceso. Cálculos e iteraciones que pueden requerir la reunión o finalización una vez se alcance un punto de ejecución.
Esta clase como advierten en [1, 2] es idónea para:
- Procesos de múltiples fases
- Algoritmos iterativos
- Cálculos paralelos
4. Práctica: Código C#
Escribamos un ejemplo para la sincronización de 2 threads que simulan ser los integrantes de una banda musical:
- un vocalista, y
- un guitarrista.
En la línea 10 creamos un objeto Barrier con el que queremos sincronizar dos (2) threads, y generar la notificación a modo de mensaje en la salida estándar con:
b => Console.WriteLine("Fin de la fase: {0}", b.CurrentPhaseNumber + 1)
Dentro de Main (líneas 14-24) creamos dos threads a los que asignamos la ejecución del método Tocar con los parámetros que indican:
- el integrante de la banda, y
- el instrumento que éste toca.
- Líneas 28-42: Ciclo for que itera hasta dos veces (fases/etapas).
- Línea 32: Simulación del tiempo que tarda el integrante en empezar a cantar/tocar.
- Línea 33: Muestra mensaje advirtiendo que el integrante ha empezando a ejecutar su performance.
- Línea 37: Simula el tiempo que el integrante tarda en ejecutar su performance.
- Línea 39: Muestra mensaje advirtiendo que el integrante ha finalizado de ejecutar su performance.
- Línea 41: Con esta línea sincronizamos la finalización de cada etapa/fase del performance (ejecución) de los integrantes (threads) de la banda: punto de sincronización.
Compilación:
- csc /target:exe SincronizacionBanda.cs
Ejecución assembly:
- .\SincronizacionBanda.exe
> Prueba de ejecución: ideone.com
5. Conclusiones
Hemos usado la clase System.Threading.Barrier para la sincronización de múltiples threads para que una vez éstos alcancen un punto específico de la ejecución de un proceso emitan una señal de registro (o reunión) para la generación de una acción/notificación en particular. Este tipo de sincronziación, como vimos, es útil para algoritmos basados en iteración que requieren la acción de múltiples threads para completar su tarea.
En la próxima receta multithreading en C# estudiáremos la clase ReaderWriterLockSlim para crear un mecanismo seguro de sincronización sobre un rescurso compartido.
6. Glosario
- Algoritmo iterativo
- Barrier
- Cálculo
- Etapa
- Fase
- Iteración
- Loop
- Multithreading
- Recurso compartido
- Sincronización
7. Literatura & Enlaces
[1]: Multithreading in C# 5.0 Cookbook by Eugene Agafonov. Copyright 2013 Eugene Agafonov, 978-1-84969-764-4.[2]: Barrier Class (System.Threading) - https://msdn.microsoft.com/en-us/library/system.threading.barrier(v=vs.110).aspx
J
No hay comentarios:
Publicar un comentario
Envíe sus comentarios, dudas, sugerencias, críticas. Gracias.