Hilos y simultaneidad

 Hilos y simultaneidad


Concepto: Un hilo es un subproceso de un proceso. Los hilos pueden tener a su vez hilos, es decir, subprocesos.


Todo programa parte inicialmente con un único hilo principal, el sistema operativo ofrece la posibilidad de hacer llamadas al sistema para poder crear y destruir estos hilos. Además, un proceso puede tener uno o más hilos.



Veamos un ejemplo de un programa multihilos con python.


import threading
import time

def saludar(number_of_thread):
    print("Hola mundo desde hilo: " + number_of_thread)
    time.sleep(5)

if __name__ == '__main__':
    for i in range(0, 3):
        thread = threading.Thread(target=saludar, args=(str(i),))
        thread.start()

        thread.join()       

    print("Hola mundo desde hilo principal")



El hilo principal del programa será main, tenemos una función saludar que simplemente imprime “Hola mundo”. 


En el hilo principal estamos haciendo una llamada a la biblioteca threading para crear un hilo, a esta llamada le pasamos la función saludar. 


Implementaremos un ciclo for, donde crearemos 3 hilos y su le pasaremos un argumento con el número correspondiente de hilo. A su vez, desde el hilo principal imprimimos “Hola mundo desde el hilo principal”. El método start inicia el hilo, y el método join esperará a que se ejecute el hilo.


¿Qué pasará?


Cuando el programa llega a la función principal, la ejecución queda en bucle mientras se crean los hilos. Al terminar la ejecución de los hilos se continuará con el hilo principal.


Si quitamos el método join(), los hilos se ejecutarán paralelamente al hilo principal.


Procesos con un único hilo vs. con múltiples hilos




Sistemas operativos multihilos: Esto significa que un SO es capaz de mantener varios hilos de ejecución dentro de un mismo proceso. La mayoría de SO modernos son capaces de esto.




Beneficios:


Cuando tienes un programa mono-hilo, se va a ejecutar secuencialmente y se desaprovecha el sistema multihilos. 


Si el programa se pudiera ejecutar paralelamente, dedicando partes de ejecución a hilos se reduciría el tiempo de ejecución.



Hilos a nivel Kernel y a nivel Usuario


En primera instancia si el kernel (sistema operativo) ni el hardware (CPU) soportan múltiples hilos y se rigen por un único proceso o hilo principal, se usará algo llamado “Planificador de hilos”.


EL planificador de hilos, selecciona qué hilo debe estar en ejecución. Los hilos a este nivel no serán vistos por el kernel ni por el hardware. Esta es una manera de poder implementar hilos en sistemas operativos que no son capaces de planificar hilos.


Ejemplo: Primeras implementaciones de Unix.


Si a nivel Hardware el procesador tiene más de un núcleo, pero el sistema operativo solo reconoce un hilo por proceso, el SO seguirá usando un sólo núcleo del procesador.


Ahora, si el SO reconoce más de un hilo por proceso el planificador del SO se encargará de decidir qué hilo se enviará al núcleo del CPU.

Los hilos son reconocidos por el kernel de esta manera. Ejemplos: Windows 95/98/NT, Solaris, Linux, Mac OS


Si existe más de un núcleo del procesador, el planificador del SO puede planificar los hilos a diferentes núcleos.


 



Modelos Multihilos


Estos modelos son las relaciones posibles entre hilos a nivel usuario e hilos a nivel kernel.


  1. Muchos a uno: Muchos hilos a nivel usuario mapeados a un solo hilo a nivel kernel. Este modelo es usado en sistemas que no reconocen los hilos a nivel kernel.

Los hilos pueden tener 3 estados: listo, ejecución y bloqueado. Si el proceso a nivel kernel está bloqueado, no importa si los hilos a nivel usuario tienen un estado de ejecución o listo, todo el proceso estará bloqueado.


Si el proceso a nivel kernel por obra del SO está en estado listo, no importa que los hilos a nivel usuario tengan como estado ejecución, no se estará ejecutando el proceso.


Ahora bien, si el proceso a nivel kernel está en estado ejecución por que así lo decidió el SO, los hilos a nivel usuario con estado ejecución ahora sí serán ejecutados.


Entonces, los hilos a nivel usuario solo pueden ser ejecutados sí:

  1. El proceso a nivel kernel está en estado: ejecución

  2. El planificador de hilos del usuario designó al hilo el estado: ejecución.

  3. NO ejecutará el hilo si:

    1. El hilo a nivel usuario está en estado: listo.

    2. El proceso a nivel kernel está en estado: listo.


  1. Uno a uno: Cada hilo a nivel usuario corresponde a un hilo a nivel kernel.


  1. Muchos a muchos: Se va a tener muchos hilos a nivel usuario que van a estar mapeados a muchos hilos a nivel kernel. Supongamos que tenemos 4 hilos a nivel usuario, pero solo 3 hilos a nivel kernel, esto quiere decir que solo 3 hilos a nivel usuario podrán ser ejecutados por los hilos a nivel kernel y tendrán que turnarse la ejecución.


Veamos un ejemplo con estos modelos en una arquitectura multihilo.


Un proceso ligero es un hilo de ejecución en un proceso.




Arquitecturas multicore


En la década de los 90 's, los procesadores tendían a duplicar su velocidad cada 18 meses, pero llegó un punto en el que esto dejó de suceder.


¿Por qué? 


Demos un vistazo a esta gráfica.




En el eje (x) podemos ver la frecuencia (velocidad) en GHz de la CPU, mientras en el eje (y) la potencia (energía) en W que se requiere para que el procesador vaya a esa velocidad.


Hay una subida abrupta de energía requerida cuando se llega a velocidades de 2.8 GHz, quiere decir que la potencia no aumenta de forma proporcional con la velocidad del CPU. Entonces, se llegó a la conclusión de que a menor velocidad de los núcleos podemos ahorrar potencia y agregar más núcleos. Expliquemos porque:


Si agregamos velocidad al núcleo un 20% (over-clocking), la energía requerida (+73%) será mayor al rendimiento (+13%) que tendrá el núcleo. 


En cambio sí, disminuimos un 20% (underclocking) la velocidad del núcleo, la energía requerida disminuirá un 49% y lo importante: el rendimiento solo baja un 13%. Ahora si agregamos un segundo núcleo a una velocidad un poco más baja, entre ambos núcleos estarán consumiendo solo un 2% más de energía y el rendimiento aumenta hasta un 73%.





Aplicación multihilos arquitectura multicore


¿Para qué me sirven los hilos en una arquitectura donde haya múltiples CPU ’s?


Con un solo hilo, una aplicación no puede sacar provecho a una arquitectura con múltiples CPU ‘s, sino hay multihilos se hace uso intensivo de un solo core y se desaprovecha esta arquitectura.


Con varios hilos cada hilo puede ejecutar una parte del proceso en un core diferente, se puede aprovechar el paralelismo. Un hilo debe ser una funcionalidad de la aplicación bien diferenciada y con una carga de CPU intensiva.


Publicar un comentario

Artículo Anterior Artículo Siguiente