Professional Documents
Culture Documents
Las posibilidades
Existen diversos casos en los que se puede amplear la programación
mediante hilos. Algunas ideas:
Si creamos un programa cin interfaz MDI (Multiple Document Interface), es
recomendable asignar separadamente cada ventana en un hilo propio
Si un programa necesita un largo tiempo para refrescar una imagen por la
complejidad del tipo de gráfico (como puede ocurrir en diseños CAD/CAM),
es conveniente crear en un hilo separado el manejador del proceso que
realiza el redibujado. Mientras, el interfaz de usuario estará activo y el hilo
de redibujado podrá trabajar en segundo plano.
En programas de simulación, por ejemplo los referentes a simulación de
actividad organica en un entorno determinado,el diseño de estos programas
es, a menudo, más simple si cada entidad está en un hilo propio, puesto
que así son más independientes y pueden presentar respuestas
individuales.
Si una parte del programa debe responder con una mayor prioridad para
responder más rápidamente a los eventos, el problema se puede resolver
más fácilmente utilizando la prioridad de los hilos. De esta manera se
reciben los ciclos de CPU necesarios para acabar la tarea y posteriormente
pasar a un modo sleep hasta que no llegue el próximo evento a tratar.
En una máquina con múltiples procesadores podemos aprovechar la
potencia de estas CPU si el programa está dividido en hilos, porque cada
cpu podrá ejecutar un hilo distinto en el mismo instante, mientras que si
sólo tenemos un hilo, el programa se ejecutará normalmente en uno de los
procesadores, quedando el resto desocupados y, por tanto,
desaprovechados. (Recordemos que NT puede ejecutar procesos en varias
cpu’s).
Introducción
Ejemplo 1
Para algunas personas la idea de crear multiples hilos en un proceso
requiere de cierta preparacion mental. Comencemos por un simple ejemplo de
cómo trabajan los hilos en la API Win32.
El código siguiente contiene un ejemplo de un simple hilo. En este
programa el código imprime el valor de una variable global llamada contador
cada vez que el usuario pulsa una tecla. Nada en el programa cambia el valor de
la variable y siempre se imprime cero (0):
#include <windows.h>
#include <iostream.h>
UINT contador;
void main(void)
{
CHAR retStr[100];
contador=0;
while(1)
{
cout << "Pulsa <ENTER> para ver el valor del contador ... ";
cin.getline(retStr, 100);
cout << "El valor es: " << contador << endl << endl;
}
}
void CountThread()
{
while(1)
{
contador++;
Sleep(100);
}
}
void main(void)
{
HANDLE countHandle;
DWORD threadID;
CHAR retStr[100];
contador=0;
countHandle=CreateThread(0, 0,
(LPTHREAD_START_ROUTINE) CountThread,
0, 0, &threadID);
if (countHandle==0)
cout << "No se puede crear el hilo: " << GetLastError() << endl;
while(1)
{
cout << "Pulsa <ENTER> para ver el valor del contador... ";
cin.getline(retStr, 100);
cout << "El valor es: " << contador << endl << endl;
}
}
La secuencia del programa ppal., el hilo y la variable global se muestran a
continuación:
El código comienza creando un hilo con la función CreateThread de la API.
CreateThread acepta como parametro el nombre de la funcion que se ejecutará
en 2º plano (thread function), esta se llama CountThread. CreateThread devuelve
el identificador y manejador del hilo creado.
También es posible activar el hilo si , de inicio , está suspendido. Debemos
decir que un hilo no consume CPU si se encuentra suspendido.
La función Sleep es una forma eficiente de realizar un retardo. Existen
otros mecanismos como lo bucles, pero todos ellos consumen ciclos de CPU.
Ejemplo 2
El codigo mostrado abajo representa cómo pasar un parametro (integer) a
la función del hilo y cómo esperar la finalizacion del hilo.
#include <windows.h>
#include <stdlib.h>
#include <iostream.h>
cin.getline(iterStr, 100);
iterations=atoi(iterStr);
honkHandle=CreateThread(0, 0,
(LPTHREAD_START_ROUTINE) HonkThread,
(VOID *) iterations, 0, &threadID);
int contador=0;
while ( WaitForSingleObject(honkHandle, 0)== WAIT_TIMEOUT)
{
cout << "esperando la finalizacion del hilo"<< contador++ << endl;
}
}
#include <windows.h>
#include <stdlib.h>
#include <iostream.h>
typedef struct
{
DWORD frequencia
DWORD duracion;
DWORD iteracion;
} honkParams;
void main(void)
{
HANDLE honkHandle;
DWORD threadID;
honkParams params;
CHAR freqStr[100];
CHAR durStr[100];
CHAR iterStr[100];
honkHandle=CreateThread(0, 0,
(LPTHREAD_START_ROUTINE) HonkThread,
¶ms, 0, &threadID);
WaitForSingleObject(honkHandle, INFINITE);
}
En el anterior codigo los tres valores introducidos por el usuario son puestos
en la estructura que es pasada el hilo. En el programa principal se llama a la
funcion WaitForSingleObject para evitar la finalizacion antes de que el hilo haya
completado su ejecucion. Sin esta llamada el programa principal terminaria y
'mataria' al proceso del hilo.
Ejemplo 3
El siguiente codigo es mas completo y muestra como es posible crear
multiples hilos, declarando varias funciones de hilos o llamando a un hilo varias
veces.
#include <windows.h>
#include <stdlib.h>
#include <iostream.h>
typedef struct
{
DWORD frequencia
DWORD duracion;
DWORD iteracion;
} honkParams;
GlobalFree(params);
}
void main(void)
{
HANDLE honkHandles[3]; // definimos tres manejadores
DWORD threadID;
honkParams *params;
DWORD count;
CHAR freqStr[100];
CHAR durStr[100];
CHAR iterStr[100];
honkHandles[count]=CreateThread(0, 0,
(LPTHREAD_START_ROUTINE) HonkThread,
//duda, viene sin &!!! ¶ms, 0, &threadID);
}