[C con Clase] Ayuda con threads

Steven Davidson steven en conclase.net
Mie Mayo 2 00:12:26 CEST 2007


Hola Carlos,

El pasado 2007-04-29 13:24:10, Carlos Rodriguez escribió:

CR> Hola, bueno estoy haciendo un programilla con c++ y me han dicho que necesito aprender sobre threads porque al hacer un bucle mi programa se queda bloqueado, entonces me gustaria aprender sobre esto, he estado mirando en MSDN y google, pero entre que viene en ingles, y que no entiendo casi nada... es complicado para mi.
CR> Entonces yo quiero saber como puedo iniciar un thread, como hacer que un codigo se ejecute cada tantos segundos (por ejemplo cada 1 segundo) y sobre todo, muy importante, donde he de poner cada parte del codigo... explicado asi por encima :]
CR>  

Veamos. Un hilo (thread, en inglés) es un "mini-programa" que se ejecuta por su cuenta. Para crear un hilo, usamos 'CreateThread()', donde pasamos una función que tú mismo crearás al igual que un parámetro para tal función. Por ejemplo,

struct info
{
  int entrada;
  int resultado;
};

DWORD WINAPI HacerAlgo( LPVOID pParam )
{
  info *pInfo = (info *) pParam;

  // Hacer lo que tengas que hacer
  ...
  return 0L;  // por ejemplo
}
...
HANDLE hHilo;
DWORD dwID;
info *pInfo;
...
pInfo = new info;
pInfo->entrada = 100;
pInfo->salida = 0;

hHilo = CreateThread( NULL, 0, HacerAlgo, pInfo, &dwID );
...

Cuando se haya terminado el hilo, debemos cerrar el manipulador con 'CloseHandle()'.

Una posibilidad es crear el hilo según la acción del usuario; por ejemplo, al pulsar un botón, o algo parecido. Como no podemos estar completamente seguros de cuándo se termine un hilo, a más tardar cerraremos todos los hilos al cerrarse la aplicación principal al procesar el mensaje 'WM_DESTROY'.


Para ejecutar un código periódicamente, sugiero usar temporizadores. Esto se hace con 'SetTimer()' para crear cualquier temporizador y 'KillTimer()' para desactivarlo. Tenemos dos opciones:
1. Procesar el mensaje WM_TIMER. Por ejemplo,

case WM_CREATE:
  SetTimer( hwnd, 1, 10000, NULL );  // Temporizador #1 cada 10 segundos
  SetTimer( hwnd, 64, 100, NULL );   // Temporizador #64 cada 100 milisegundos
return 0;

case WM_TIMER:
  if( 1 == wParam )
  {
     // Hacer algo aquí para el temporizador #1
  }
  else if( 64 == wParam )
  {
     // Hacer algo aquí para el temporizador #64
  }
return 0;

2. Indicar una función propia que se ejecutará periódica y automáticamente. Por ejemplo,

VOID CALLBACK MiFuncion(
  HWND hwnd,         // manipulador a la ventana
  UINT uMsg,         // mensaje WM_TIMER
  UINT_PTR idEvent,  // identificador el temporizador/reloj/alarma
  DWORD dwTime       // hora actual del sistema = GetTickCount()
)
{
  // Hacemos algo
  ...
}

case WM_CREATE:
  // Cada 50 segundos invocamos 'MiFuncion()'
  SetTimer( NULL, 32, 50000, MiFuncion );
  ...


Sin saber exactamente lo que quieres hacer, no te puedo dar una solución concreta a tu problema.


Espero que esto te oriente.

Steven


Más información sobre la lista de distribución Cconclase