elhacker.net cabecera Bienvenido(a), Visitante. Por favor Ingresar o Registrarse
¿Perdiste tu email de activación?.

 

 


Tema destacado: Arreglado, de nuevo, el registro del warzone (wargame) de EHN


+  Foro de elhacker.net
|-+  Programación
| |-+  Programación C/C++ (Moderadores: Eternal Idol, Littlehorse, K-YreX)
| | |-+  ¿Qué esta mal con esta creacion de HILO (Thread)?
0 Usuarios y 1 Visitante están viendo este tema.
Páginas: [1] Ir Abajo Respuesta Imprimir
Autor Tema: ¿Qué esta mal con esta creacion de HILO (Thread)?  (Leído 3,221 veces)
yovaninu


Desconectado Desconectado

Mensajes: 349



Ver Perfil
¿Qué esta mal con esta creacion de HILO (Thread)?
« en: 17 Septiembre 2011, 21:57 pm »

Buenas a todos, googleando, encontre este ejemplo de creacion de un HILO y modificandolo un poco llama a una funcion y ésta a su vez ejecuta un bucle de 1000 iteraciones, al hacerlo correr en VS2005, la ventana tipica aparece pero al parecer la aplicacion o no crea el hilo o no detecta cuando éste ha terminado, les dejo el codigo:
Código
  1. #define _WIN32_WINNT 0x0500
  2. #define _CRT_SECURE_NO_DEPRECATE
  3. #include <windows.h>
  4. #include <stdlib.h>
  5. #include <string.h>
  6. #include <tchar.h>
  7. #include <string>
  8. #include <atlstr.h>
  9.  
  10. /*Declaraciones para nuestro hilo*/
  11. DWORD WINAPI ThreadFunc( LPVOID );
  12. UINT TerminoProceso;
  13. static DWORD dwThreadId;
  14. static HANDLE hThread=NULL;
  15. DWORD cod;
  16. char cade[20];
  17.  
  18.  
  19.  
  20.  
  21. MSG messages;
  22.  
  23. // Global variables
  24. int a;
  25. int b;
  26. int c;
  27. CString t;
  28.  
  29.  
  30.  
  31. // El nombre de la clase de la ventana principal
  32. static TCHAR szWindowClass[] = _T("VentanaWin32");
  33.  
  34. // El texto que aparece en la ventana principal
  35. static TCHAR szTitle[] = _T("Una ventana tipica de win32");
  36.  
  37.  
  38. HINSTANCE hInst; //variable global para
  39.  
  40. //El propósito de esta función es procesar cualquier mensaje que nuestra aplicación reciba del sistema operativo
  41. LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
  42.  
  43. /************************************************************/
  44. /************************FUNCION PRINCIPAL*******************/
  45. /************************************************************/
  46. int WINAPI WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
  47. {
  48.  
  49.  
  50. /*Creamos el hilo*/
  51. hThread = CreateThread(
  52. NULL, // sin atributos de seguridad
  53. 0, // Tamaño de la pila por defecto
  54. ThreadFunc, // Funcion del hilo
  55.        hInstance, // argumento de la funcion del hilo (pasado por referencia)
  56. 0, // creacion de banderas por defecto
  57. &dwThreadId); // puntero a la variable donde se guardara el id del hilo
  58.  
  59.  
  60.  
  61.  
  62.    //Esta estructura contiene información sobre la ventana, tal como el icono de la aplicación,
  63. //el color de fondo de la ventana, el nombre que aparece en la barra de título,
  64. //el nombre de la función de procedimiento de ventana, etc.
  65. WNDCLASSEX wcex;
  66.  
  67.    wcex.cbSize = sizeof(WNDCLASSEX);
  68.    wcex.style          = CS_HREDRAW | CS_VREDRAW;
  69.    wcex.lpfnWndProc    = WndProc;
  70.    wcex.cbClsExtra     = 0;
  71.    wcex.cbWndExtra     = 0;
  72.    wcex.hInstance      = hInstance;
  73.    wcex.hIcon          = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_ASTERISK));
  74.    wcex.hCursor        = LoadCursor(NULL, IDC_ARROW);
  75.    wcex.hbrBackground  = (HBRUSH)(COLOR_WINDOW+1);
  76.    wcex.lpszMenuName   = NULL;
  77.    wcex.lpszClassName  = szWindowClass;
  78.    wcex.hIconSm        = LoadIcon(wcex.hInstance, MAKEINTRESOURCE(IDI_ASTERISK));
  79.    if (!RegisterClassEx(&wcex)){
  80.        MessageBox(NULL,
  81.            _T("Call to RegisterClassEx failed!"),
  82.            _T("Win32 Guided Tour"),
  83.            NULL);
  84.        return 1;
  85.    }    
  86. hInst = hInstance;
  87.    HWND hWnd = CreateWindow(
  88.        szWindowClass,
  89.        szTitle,
  90.        WS_OVERLAPPEDWINDOW,
  91.        CW_USEDEFAULT, CW_USEDEFAULT,
  92.        500, 200,
  93.        NULL,
  94.        NULL,
  95.        hInstance,
  96.        NULL
  97.    );
  98.    ShowWindow(hWnd,
  99.        nCmdShow);
  100.    UpdateWindow(hWnd);
  101.  
  102.    MSG msg;
  103.    while (GetMessage(&msg, NULL, 0, 0))
  104.    {
  105.        TranslateMessage(&msg);
  106.        DispatchMessage(&msg);
  107.    }
  108.  
  109.    return (int) msg.wParam;
  110. }
  111.  
  112.  
  113.  
  114.  
  115. /*Funcion que sera ejecutada por el HILO*/
  116. DWORD WINAPI ThreadFunc( LPVOID lpParam )
  117. {
  118. int i,j=0,l=0;
  119. HWND *mhwnd,mHwnd;
  120.  
  121. mhwnd=(HWND*)lpParam;
  122. mHwnd=*mhwnd;
  123.  
  124.  
  125. for(i=0;i<10000;i++)
  126. {
  127. j++;
  128. }
  129. PostMessage(mHwnd,TerminoProceso,0,0); //cuando finalice...
  130. return (DWORD)l;
  131. }
  132.  
  133.  
  134. //Callback de los mensajes...
  135. LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
  136. {
  137.    PAINTSTRUCT ps;
  138.    HDC hdc;
  139.    TCHAR greeting[] = _T("Probando Hilos...");
  140.  
  141.  
  142.  
  143. /*para reconocer cuando termina el HILO y asi poder destruirlo*/
  144. if(message==TerminoProceso)
  145. {
  146. cod=GetExitCodeThread(hThread,&cod);
  147. while(cod==STILL_ACTIVE)
  148. {
  149. GetExitCodeThread(hThread,&cod);
  150. }
  151. a=(int)cod;
  152. itoa(a,cade,10);
  153. MessageBoxW(hWnd,L"dddd",L"info",MB_ICONINFORMATION);
  154. CloseHandle(hThread);
  155. hThread=NULL;
  156. return 0;
  157. }
  158.  
  159.  
  160. //procesamos los mensajes principales
  161. switch (message)
  162.    {
  163.  
  164. case WM_CREATE:
  165. /*registramos un nuestro mensaje personalizado para detectar el momento en que el hilo termina*/
  166. TerminoProceso=RegisterWindowMessage("ProcesoFin");
  167. break;
  168.  
  169.    case WM_PAINT:
  170.        hdc = BeginPaint(hWnd, &ps);
  171. /*un mensaje comun en la ventana*/
  172.        TextOut(hdc,5, 5,greeting, _tcslen(greeting));
  173.        EndPaint(hWnd, &ps);
  174.    break;
  175.  
  176.  
  177.    case WM_DESTROY:
  178.        PostQuitMessage(0);
  179.        break;
  180.  
  181.    default:
  182.        return DefWindowProc(hWnd, message, wParam, lParam);
  183.        break;
  184.    }
  185.  
  186.    return 0;
  187. }
  188.  
  189.  

Pienso que estoy pasando mal algun parametro a CreateThread, alguna sugerencia.???


En línea

Eternal Idol
Kernel coder
Moderador
***
Desconectado Desconectado

Mensajes: 5.966


Israel nunca torturó niños, ni lo volverá a hacer.


Ver Perfil WWW
Re: ¿Qué esta mal con esta creacion de HILO (Thread)?
« Respuesta #1 en: 17 Septiembre 2011, 22:21 pm »

El hilo es creado, el problema esta en el parametro. En hInstance no esta el HWND sino la cabecera del ejecutable (MZ). Por logica el hilo lo tenes que crear DESPUES de crear la ventana si le queres pasar el HWND de la misma ...

Simple solucion:

En WinMain moves la llamada a CreateThread a justo despues de
Código:
UpdateWindow(hWnd);

Y en lugar de pasar hInstance como parametro al hilo pasas hWnd.

En ThreadFunc:
Código:
HWND mHwnd = (HWND)lpParam;


« Última modificación: 17 Septiembre 2011, 22:28 pm por Eternal Idol » En línea

La economía nunca ha sido libre: o la controla el Estado en beneficio del Pueblo o lo hacen los grandes consorcios en perjuicio de éste.
Juan Domingo Perón
yovaninu


Desconectado Desconectado

Mensajes: 349



Ver Perfil
Re: ¿Qué esta mal con esta creacion de HILO (Thread)?
« Respuesta #2 en: 18 Septiembre 2011, 05:45 am »

En efecto, funciona.

Gracias Eternal Idol, supongo que al implementar otras cosas de esta forma me surgiran otros problemas, espero contra siempre con vuestra ayuda.

Dejo el code completo funcional para aquel que se inicie en esto de los HIlos aunque he modificado la funcion que ejecuta el hilo para que demore exagerando un poco.

La pregunta es como haria para mostrar en el cuadro de texto el valor de la variable 'LINC' que se supone se incrementa mientras los bucles del hilo se ejecutan, la finalidad era mostrar el valor final de 'LINC' cuando el hilo termina en un MessageBox, por ahora solo muestra 1. A ver si ponemos 100% funcional el ejemplo.

Código
  1. #define _WIN32_WINNT 0x0500
  2. #define _CRT_SECURE_NO_DEPRECATE
  3. #include <windows.h>
  4. #include <stdlib.h>
  5. #include <string.h>
  6. #include <tchar.h>
  7. #include <string>
  8. #include <atlstr.h>
  9.  
  10. /*Declaraciones para nuestro hilo*/
  11. DWORD WINAPI ThreadFunc( LPVOID );
  12. UINT TerminoProceso;
  13. static DWORD dwThreadId;
  14. static HANDLE hThread=NULL;
  15. DWORD cod;
  16. char cade[10];
  17.  
  18.  
  19.  
  20.  
  21. MSG messages;
  22.  
  23. // Global variables
  24. char a;
  25. int LINC=0;
  26.  
  27.  
  28.  
  29.  
  30.  
  31. // El nombre de la clase de la ventana principal
  32. static TCHAR szWindowClass[] = _T("VentanaWin32");
  33.  
  34. // El texto que aparece en la ventana principal
  35. static TCHAR szTitle[] = _T("Una ventana tipica de win32");
  36.  
  37.  
  38. HINSTANCE hInst; //variable global para
  39.  
  40. //El propósito de esta función es procesar cualquier mensaje que nuestra aplicación reciba del sistema operativo
  41. LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
  42.  
  43. /************************************************************/
  44. /************************FUNCION PRINCIPAL*******************/
  45. /************************************************************/
  46. int WINAPI WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
  47. {
  48.  
  49.  
  50.  
  51.  
  52.  
  53.  
  54.  
  55.    //Esta estructura contiene información sobre la ventana, tal como el icono de la aplicación,
  56. //el color de fondo de la ventana, el nombre que aparece en la barra de título,
  57. //el nombre de la función de procedimiento de ventana, etc.
  58. WNDCLASSEX wcex;
  59.  
  60.    wcex.cbSize = sizeof(WNDCLASSEX);
  61.    wcex.style          = CS_HREDRAW | CS_VREDRAW;
  62.    wcex.lpfnWndProc    = WndProc;
  63.    wcex.cbClsExtra     = 0;
  64.    wcex.cbWndExtra     = 0;
  65.    wcex.hInstance      = hInstance;
  66.    wcex.hIcon          = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_ASTERISK));
  67.    wcex.hCursor        = LoadCursor(NULL, IDC_ARROW);
  68.    wcex.hbrBackground  = (HBRUSH)(COLOR_WINDOW+1);
  69.    wcex.lpszMenuName   = NULL;
  70.    wcex.lpszClassName  = szWindowClass;
  71.    wcex.hIconSm        = LoadIcon(wcex.hInstance, MAKEINTRESOURCE(IDI_ASTERISK));
  72.    if (!RegisterClassEx(&wcex)){
  73.        MessageBox(NULL,
  74.            _T("Call to RegisterClassEx failed!"),
  75.            _T("Win32 Guided Tour"),
  76.            NULL);
  77.        return 1;
  78.    }    
  79. hInst = hInstance;
  80.    HWND hWnd = CreateWindow(
  81.        szWindowClass,
  82.        szTitle,
  83.        WS_OVERLAPPEDWINDOW,
  84.        CW_USEDEFAULT, CW_USEDEFAULT,
  85.        500, 200,
  86.        NULL,
  87.        NULL,
  88.        hInstance,
  89.        NULL
  90.    );
  91.    ShowWindow(hWnd,nCmdShow);
  92.    UpdateWindow(hWnd);
  93.  
  94. /*Creamos el hilo*/
  95. hThread = CreateThread(
  96. NULL, // sin atributos de seguridad
  97. 0, // Tamaño de la pila por defecto
  98. ThreadFunc, // Funcion del hilo
  99.        hWnd, // argumento de la funcion del hilo (pasado por referencia)
  100. 0, // creacion de banderas por defecto
  101. &dwThreadId); // puntero a la variable donde se guardara el id del hilo
  102.  
  103.  
  104.    MSG msg;
  105.    while (GetMessage(&msg, NULL, 0, 0))
  106.    {
  107.        TranslateMessage(&msg);
  108.        DispatchMessage(&msg);
  109.    }
  110.  
  111.    return (int) msg.wParam;
  112. }
  113.  
  114.  
  115.  
  116.  
  117. /*Funcion que sera ejecutada por el HILO*/
  118. DWORD WINAPI ThreadFunc( LPVOID lpParam )
  119. {
  120. int i,j=0,k,s;
  121.    HWND mHwnd = (HWND)lpParam;
  122.  
  123. for(i=0;i<1000;i++)
  124.  for(k=0;k<4000;k++)
  125.  for(s=0;s<90;s++)
  126.     LINC++; /*Variable que se incrementa*/
  127.  
  128. PostMessage(mHwnd,TerminoProceso,0,0);
  129. return (DWORD)LINC; /*Devolvemos la variable cuando finaliza este hilo*/
  130. }
  131.  
  132.  
  133. //Callback de los mensajes...
  134. LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
  135. {
  136.    PAINTSTRUCT ps;
  137.    HDC hdc;
  138.    TCHAR greeting[] = _T("Probando Hilos...");
  139.  
  140.  
  141.  
  142. /*para reconocer cuando termina el HILO y asi poder destruirlo*/
  143. if(message==TerminoProceso)
  144. {
  145. cod=GetExitCodeThread(hThread,&cod);
  146. while(cod==STILL_ACTIVE)
  147. {
  148. GetExitCodeThread(hThread,&cod);
  149. }
  150. a=(int)cod;
  151. itoa(a,cade,20);
  152.  
  153. /*Aqui deberiamos mostrar el ultimo valor de la variable 'LINC'*/
  154. MessageBoxW(hWnd,(LPWSTR)cade,L"El hilo a Finalizado",MB_ICONINFORMATION);
  155.  
  156. CloseHandle(hThread);
  157. hThread=NULL;
  158. return 0;
  159. }
  160.  
  161.  
  162. //procesamos los mensajes principales
  163. switch (message)
  164.    {
  165.  
  166.    case WM_CREATE:
  167. /*registramos un nuestro mensaje personalizado para detectar el momento en que el hilo termina*/
  168. TerminoProceso=RegisterWindowMessage("ProcesoFin");
  169.    break;
  170.  
  171.    case WM_PAINT:
  172.        hdc = BeginPaint(hWnd, &ps);
  173.        TextOut(hdc,5, 5,greeting, _tcslen(greeting));
  174.        EndPaint(hWnd, &ps);
  175.    break;
  176.  
  177.  
  178.    case WM_DESTROY:
  179.        PostQuitMessage(0);
  180.        break;
  181.  
  182.    default:
  183.        return DefWindowProc(hWnd, message, wParam, lParam);
  184.        break;
  185.    }
  186.  
  187.    return 0;
  188. }
  189.  
  190.  

En línea

Eternal Idol
Kernel coder
Moderador
***
Desconectado Desconectado

Mensajes: 5.966


Israel nunca torturó niños, ni lo volverá a hacer.


Ver Perfil WWW
Re: ¿Qué esta mal con esta creacion de HILO (Thread)?
« Respuesta #3 en: 18 Septiembre 2011, 11:41 am »

No tiene ningun sentido usar mas variables globales que LINC, no tenes que asignarle el resultado de GetExitCodeThread a cod (es un bool y el while no se ejecuta nunca de esa manera) y no podes llamar a MessageBoxW con una cadena ASCII por mas que le hagas un casting a wide:

Código
  1. DWORD cod;
  2. GetExitCodeThread(hThread,&cod);
  3. while (cod == STILL_ACTIVE)
  4. {
  5. GetExitCodeThread(hThread,&cod);
  6. }
  7. char cade[20];
  8. itoa(cod,cade,10);
  9. /*Aqui deberiamos mostrar el ultimo valor de la variable 'LINC'*/
  10. MessageBoxA(hWnd, cade, "El hilo ha Finalizado", MB_ICONINFORMATION);

PD. Si alguna vez queres acceder a una variable global desde mas de un hilo tenes que usar sincronizacion.
En línea

La economía nunca ha sido libre: o la controla el Estado en beneficio del Pueblo o lo hacen los grandes consorcios en perjuicio de éste.
Juan Domingo Perón
Páginas: [1] Ir Arriba Respuesta Imprimir 

Ir a:  

WAP2 - Aviso Legal - Powered by SMF 1.1.21 | SMF © 2006-2008, Simple Machines