Una introducción a subprocesos en VB.NET

Para comprender los subprocesos en VB.NET, es útil comprender algunos de los conceptos básicos. Lo primero es que el enhebrado es algo que sucede porque el sistema operativo lo admite. Microsoft Windows es un sistema operativo multitarea preventivo. Una parte de Windows llamada el programador de tareas distribuye el tiempo del procesador a todos los programas en ejecución. Estos pequeños fragmentos de tiempo de procesador se denominan segmentos de tiempo. Los programas no están a cargo de la cantidad de tiempo de procesador que obtienen, sino del programador de tareas. Debido a que estos intervalos de tiempo son tan pequeños, te da la ilusión de que la computadora está haciendo varias cosas a la vez.

Definición de hilo

Un hilo es un flujo de control secuencial único.

Algunos calificadores:

  • Un hilo es una "ruta de ejecución" a través de ese cuerpo de código.
  • Los subprocesos comparten memoria, por lo que deben cooperar para producir el resultado correcto.
  • Un subproceso tiene datos específicos del subproceso, como registros, un puntero de pila y un contador de programa..
  • Un proceso es un solo cuerpo de código que puede tener muchos hilos, pero tiene al menos uno y tiene un solo contexto (espacio de direcciones).

Esto es algo de nivel de ensamblaje, pero eso es en lo que te encuentras cuando comienzas a pensar en hilos.

Multithreading vs. Multiprocesamiento

El subprocesamiento múltiple no es lo mismo que el procesamiento paralelo multinúcleo, pero el subprocesamiento múltiple y el multiprocesamiento funcionan juntos. La mayoría de las PC de hoy en día tienen procesadores que tienen al menos dos núcleos, y las máquinas domésticas comunes a veces tienen hasta ocho núcleos. Cada núcleo es un procesador separado, capaz de ejecutar programas por sí mismo. Obtiene un aumento de rendimiento cuando el sistema operativo asigna un proceso diferente a diferentes núcleos. El uso de múltiples hilos y múltiples procesadores para un rendimiento aún mayor se llama paralelismo a nivel de hilo.

Mucho de lo que se puede hacer depende de lo que el sistema operativo y el hardware del procesador puedan hacer, no siempre lo que puede hacer en su programa, y ​​no debe esperar poder usar múltiples hilos en todo. De hecho, es posible que no encuentre muchos problemas que se beneficien de múltiples hilos. Por lo tanto, no implemente multihilo solo porque está allí. Puede reducir fácilmente el rendimiento de su programa si no es un buen candidato para subprocesamiento múltiple. Como ejemplos, los códecs de video pueden ser los peores programas para subprocesos múltiples porque los datos son inherentemente seriales. Los programas de servidor que manejan páginas web podrían estar entre los mejores porque los diferentes clientes son inherentemente independientes.

Practicando la seguridad del hilo

El código multiproceso a menudo requiere una coordinación compleja de subprocesos. Los errores sutiles y difíciles de encontrar son comunes porque los diferentes hilos a menudo tienen que compartir los mismos datos para que los datos puedan ser cambiados por un hilo cuando otro no lo espera. El término general para este problema es "condición de carrera". En otras palabras, los dos hilos pueden entrar en una "carrera" para actualizar los mismos datos y el resultado puede ser diferente dependiendo de qué hilo "gana". Como ejemplo trivial, supongamos que está codificando un bucle:

Si el contador de bucles "I" pierde inesperadamente el número 7 y pasa de 6 a 8, pero solo una parte del tiempo, tendría efectos desastrosos en lo que sea que esté haciendo el bucle. La prevención de problemas como este se llama seguridad de subprocesos. Si el programa necesita el resultado de una operación en una operación posterior, entonces puede ser imposible codificar procesos o hilos paralelos para hacerlo. 

Operaciones básicas de subprocesos múltiples

Es hora de llevar esta charla preventiva a un segundo plano y escribir un código multiproceso. Este artículo utiliza una aplicación de consola para simplificar en este momento. Si desea seguir, inicie Visual Studio con un nuevo proyecto de aplicación de consola.

El espacio de nombres principal utilizado por multithreading es el espacio de nombres System.Threading y la clase Thread creará, iniciará y detendrá nuevos hilos. En el siguiente ejemplo, observe que TestMultiThreading es un delegado. Es decir, debe usar el nombre de un método que el método Thread pueda llamar.

En esta aplicación, podríamos haber ejecutado el segundo Sub simplemente llamándolo:

Esto habría ejecutado toda la aplicación en forma serial. Sin embargo, el primer ejemplo de código anterior inicia la subrutina TestMultiThreading y luego continúa.

Un ejemplo de algoritmo recursivo

Aquí hay una aplicación multiproceso que involucra el cálculo de permutaciones de una matriz usando un algoritmo recursivo. No todo el código se muestra aquí. El conjunto de caracteres que se permutan es simplemente "1", "2", "3", "4" y "5". Aquí está la parte pertinente del código..