You are on page 1of 5

Qu es un Thread y su Uso

Un Thread es un mecanismo que permite a una aplicacin realizar varias tareas a la vez de
manera concurrente.
Se les parece al concepto de sistema operativo multitatrea?
Si, es parecido, es la misma filosofia que utiliza el OS para ejecutar varios procesos a la vez,
pero enfocada ejecutar sub procesos de un mismo proceso, lo cual es un poco diferente ya
que por definicin los procesos no comparten el espacio de memoria entre si, mientras que
los Threads (o hilos como los quieras llamar) si.

Los Threads son una ampliacin del concepto de multitarea, si bien multitarea se refiere a la
capacidad de un sistema para ejecutar varios procesos a la vez, en un comienzo esto hacia
referencia a que ms de una aplicacin se estuviera ejecutando de manera concurrente, sin
embargo pronto se hizo notoria la necesidad de que una misma aplicacin hiciera varias
cosas a la vez. All nacieron los Threads.
En un sistema multitarea podemos tener los procesos A, B y C ejecutndose
simultneamente, pero qu pasaba si el proceso A deba mostrar una interfaz grfica y de
paso estar escribiendo un archivo a la vez? no era posible.
El proceso deba terminar de escribir en disco antes de volver a trabajar en su interfaz
grfica lo cual no era precisamente algo deseable. As que surgi la idea de permitir que un
proceso pueda tener una o mas tareas ejecutndose a la vez o al menos que as lo
percibiera el usuario, de tal forma que cada vez que a un proceso le correspondiera un
Quantum de ejecucin el sistema alterne entre ejecutar una de sus tareas u otra.

Esto conlleva a la necesidad de reestructurar el concepto de proceso, ya que un proceso no


es la unidad mnima de ejecucin puesto que ahora el proceso es un conjunto de tareas (en
adelante hilos o threads).
Un proceso que en apariencia no utiliza threads realmente se esta ejecutando en un nico
thread.

Consideraciones de los Procesos y los


Thread
De acuerdo a lo que acabamos de ver debemos tener en cuenta un par de cosas.

La memoria de trabajo del proceso (de lo cual hablbamos en la parte2) sigue siendo
asignada por proceso, los thread dentro del proceso comparten todos la misma
regin de memoria, el mismo espacio de direcciones.

El sistema operativo asigna Quantums de ejecucin a cada thread creado, y en


efecto ya no calendariza procesos sino cada uno de los hilos en ejecucin en el
sistema.

Cada hilo tiene su propio contexto (estado de ejecucin), as que cada vez que que se
suspende un hilo para permitir la ejecucin de otro, su contexto es guardado y
restablecido nuevamente solo cuando es su turno de ejecucin.

Al ser la unidad mnima de ejecucin cada thread tiene su propio stack

El proceso si bien ya no es la unidad de ejecucin sigue siendo parte fundamental en


el funcionamiento del sistema ya que el proceso hace parte de la asignacin de
prioridad de ejecucin, es al que se le asigna memoria y de hecho es al que se le
asignan los recursos, as como privilegios y otros datos importantes.

El hilo es solo quien se ejecuta (sin demeritar en absoluto algo tan importante como
esto).

Usar thread no implica necesariamente


ejecucin en paralelo
Qu sucede si estamos utilizando varios threads en una aplicacin que
se ejecuta en una maquina con una sola CPU?
Si bien la impresin del usuario es que se estn ejecutando varias cosas al tiempo ya esta
claro que esto no es as pues en la CPU solo se puede ejecutar una cosa a la vez, lo que esta
pasando realmente es que los thread estn alternando tiempo de ejecucin de una manera
tan rpida que el usuario percibe que se estn ejecutando al tiempo.
Pero por otro lado...

Qu sucede si la maquina tiene ms de una CPU?

En este caso las cosas pueden cambiar, si nuestra aplicacin tiene dos hilos y nuestra
maquina tiene dos CPU (o core) en efecto cada thread se podra ejecutar en una CPU
diferente, en este caso si se puede habar de ejecucin en paralelo, aunque no

necesariamente pues puede darse el caso en que, debido a la necesidad del sistema de
calendarizar threads de otros procesos, ambos thread se ejecuten en la misma CPU en un
momento dado, en ese momento no habra paralelismo.

Pero hay otro escenario

Que pasa si mi maquina tiene 2 CPU pero mi aplicacin esta utilizando ms de 2 thread?
Lo que suceder es que solo dos de esos thread se estarn ejecutando en paralelo en un
momento dado (aunque ya vimos que esto no es necesariamente lo que sucede), y el
sistema operativo alternara la ejecucin de dichos thread de tal forma que todos tengan
Quantums asignados, pero solo podr haber mximo 2 en paralelo.

Es cierto que usar threads har que mi aplicacin se ejecute ms


rpido?
De acuerdo a lo que vimos en la seccin anterior podemos concluir rotundamente que:
DEPENDE.
Como ya vimos si tu maquina tiene solo 1 CPU realmente har tu aplicacin mas lenta, pero
con la ventaja de poder efectuar varias tareas a la vez (en apariencia), pero si tienes tantas
o ms CPU como threads en ejecucin el rendimiento si que mejorara, es decir si tienes 2
thread y 2 CPU seguramente que si estars haciendo dos cosas a la vez y no una cosa cada
vez.
El efecto contrario se evidencia toda vez que trates de ejecutar ms threads que las CPU
que tienes, es decir si vas a ejecutar 20 threads y solo tienes 2 CPU en vez de ganar
rendimiento realmente lo que hars ser castigarlo puesto que esos thread estarn
compitiendo por el tiempo de CPU, lo cual se traduce en mltiples y frecuentes cambios de
contexto que harn perder el preciado tiempo de CPU en la lgica necesaria par cambiar de
un thread a otro.
En estos escenarios es conveniente administrar la ejecucin de los thread para que solo se
ejecuten tantos thread como CPUS existan, y solo entren en ejecucin threads nuevos
cuando haya CPUS disponibles. Esto es muy engorroso de hacer pero ya hay librerias que
ayudan a esto como es el caso de TPL y sus derivados a nivel de lenguaje async/await.
Otra cosa importante de notar es que la creacin y la administracin de threads es costosa
desde el punto de vista del uso de CPU as que si una aplicacin que se ejecuta en una
maquina con ms de una CPU, requiere ejecutar una tarea cortada en partes paralelas
probablemente sea mucho mas rpido ejecutarla normalmente que abrirla en threads,
mientras que en una tareas suficientemente grande el tiempo invertido en crear y
administrar los threads puede ser proporcionalmente insignificante.

Diferencias entre Threads del kernel y


Threads de Usuario (Fibras / Fibers).
Si, hay diferentes tipos de thread, dependiendo de la estructura del sistema operativo esto
puede variar.
Pero en trminos generales existen los tipos de thread que he mencionado
inicialmente.Veremos como funciona en Windows.

Los thread de Kernel


Todo sistema operativo tiene un kernel, el kernel encargado de todo lo que en esencia es el
sistema operativo ofrece muchas funcionalidades, una de ellas crear threads ya que son su
unidad minina de ejecucin y funcionan muy bien tal como lo hemos visto.

En Windows cada vez que se crea un thread se crea un objeto del kernel que tiene toda la
informacin necesaria respecto a que proceso, cual cdigo ejecutable del thread, etc. estn
asignados a dicho thread. Este objeto thread existe en el espacio de direcciones asignadas
al kernel.
Recordemos que cada proceso solo puede acceder a los objetos o reas de memoria dentro
de su propio espacio de direcciones, entonces Cmo hace un proceso para acceder a un
objeto thread que esta en otro espacio de direcciones ( el del kernel )? bueno el kernel como
tal se encarga de eso asignndole al proceso un manejador al thread, el kernel mantiene
una tabla de que identificadores de recursos tiene asignado el proceso, as que cuando un
proceso quiere acceder a algn objeto del kernel, en este caso threads, utiliza funciones de
la API de Windows que con el identificador del objeto hacen llamados al kernel los cuales son
quienes en ultima instancia manipulan al objeto en su propio espacio de direcciones del
kernel.
Entonces, cada vez que en nuestro proceso utilizamos un thread y queremos modificar su
comportamiento o verificar su informacin estadstica lo que sucede tras bambalinas es que
se hacen llamados al kernel. El kernel proporciona acceso a funcionalidades que puedes
modificar o supervisar el funcionamiento del thread.
El kernel se encarga de manera automtica de calendarizar la ejecucin de cada uno de los
thread en ejecucin. Si un thread de un proceso invoca a un dispositivo de I/O como por
ejemplo la impresora, el thread queda suspendido hasta que la impresora le conteste pero
otros thread del mismo proceso seguirn ejecutndose.

Los thread de usuario

Bsicamente son los mismos thread de kernel con la diferencia en que estos no son
administrados por el kernel del sistema operativo, es decir el sistema operativo no sabe que
existen. Son administrados por los programas de usuario.
Un ejemplo de estos son los thread creados en .Net Framework o en java, todos estos thread
son creados, calendarizados y administrados por el runtime de cada uno de ellos, el sistema
operativo en esencia no sabe nada de ellos. Cada thread del kernel puede tener tener dentro
de si uno o mas thread de usuario. El sistema operativo solo calendariza threads de kernel.
Entonces, cada vez que en nuestro proceso utilizamos un user thread y queremos modificar
su comportamiento o verificar su informacin estadstica lo que sucede tras bambalinas es
que se hacen llamados a funciones dentro del propio espacio de direcciones del proceso y
este se encarga de hacer el trabajo necesario. En adelante me referir a los thread de
usuario como fiber.
El propio programa se encarga de manera automtica de calendarizar la ejecucin de cada
uno de los fiber en ejecucin.
Si un fiber de un proceso invoca a un dispositivo de I/O como por ejemplo la impresora, el
fiber queda suspendido hasta que la impresora le conteste pero los otros fiber del mismo
proceso tambin se bloquearan y no seguirn ejecutndose, porque? recordemos que el
sistema operativo no conoce dichos threads as que si uno se bloquea para el sistema
operativo es como si todo el proceso estuviese bloqueado as que este tipo de thread son
totalmente bloqueantes del proceso cuando estn a la espera de respuesta de un
dispositivo.
Para solucionar esto, Windows ofrece mecanismos que permiten asociar un fiber a un thread
de kernel nuevo independiente, de tal forma que si por ejemplo el java virtual machine
detecta que uno de sus thread (que son en realidad fibers) queda bloqueado en espera de
un dispositivo, la maquina de java para no bloquear los otros thread del proceso crea un

nuevo thread de sistema operativo y lo asocia con ese fiber para que el thread principal
(donde corren los demas fiber) no quede bloqueado.

Diferencias

Dado lo que he explicado anteriormente podemos contemplar los siguientes aspectos:


Los thread de usuario (fibers) son mucho ms eficientes en escenarios con varios thread que
los thread del kernel. Principalmente por dos razones:
1. Los thread de usuario no requieren ser conmutados en modo kernel sino en modo
usuario lo cual permite hacer la conmutacin entre threads de manera ms rpida al
no tener que alternar de contexto.
2. No son calendarizados de manera preferente, sino que de manera manual deben
ser suspendidos o reactivados, lo que da la opcin de hacer una calendarizacin
mucho ms adecuada de acuerdo al juego de threads que se estn ejecutando.
Los thread de usuario tienen la desventaja de que no tienen mayor soporte del sistema
operativo lo que conlleva a que hay que hacer mucho trabajo de manera manual, por
ejemplo efectuar la calendarizacin.
Los thread de usuario bloquean a todos los thread del proceso cuando estos estn
bloqueados a espera de una llamada al kernel o a un dispositivo de IO, lo cual hace que se
pierda la funcionalidad de procesamiento paralelo.
Algunos sistemas operativos como es el caso de Windows, proveen funcionalidades para
convertir fiber a kernel thread y viceversa, lo cual facilita dar solucin a estos escenarios de
bloqueo.
En trminos generales es mucho ms recomendable trabajar con Kernel Threads que con
Fibers, dada su mayor complejidad los fibers pueden traer ms problemas de lo que
solucionan. Sin embargo hay escenarios donde la implementacin de fibers es muy
recomendable y de hecho casi un deber como es en los siguientes casos:

You might also like