![]() |
Problemas con los hilos en Builder
Hola amigos, aqui otra vez con problemas :(.
El problema que tengo ahora es que estoy probando el manejo de un hilo y si uso Terminate() y FreeOnTerminate = true le doy y se termina el hilo y se destruye pero, si uso Suspend() el hilo no se detiene y sigue trabajando. Probé a poner FreeOnTerminate = false y usar WaitFor() despues de Suspend(), Resume(), o Terminate() pero me encuentro con que ejecuta cualquiera de esas lineas y llega al WaitFor() y se queda congelado todo, tanto el interfaz como el hilo. No se por qué pasa esto y ademas tuve que poner un Application->ProcessMessage() para que procese los mensajes y me deje trabajar sobre el form para poder pulsar los botones ya que si no es así no me deja hacer nada y el form se congela mientras corre el hilo ¿no se supone que los hilos son entre otras cosas para evitar eso? Es muy cortito asi que lo pongo aquí: THilo.cpp: Código:
//---------------------------------------------------------------------------Código:
//---------------------------------------------------------------------------Código:
//---------------------------------------------------------------------------Estas cosas no me pasan usando las Apis de windows ResumeThread(), SuspendThread(), CreateThread(), y TerminateThread() ¿por que pasa con el que nos da Borland? |
Acabo de ver que es un problema con Synchronize(), o sea, si uso Synchronize no me funciona ni Resume(), ni Suspend(), WaitFor(). Pero creo que voy a necesitar del uso de Synchronize ¿como lo hago?
|
bueno ya lo conseguí. Me explicaron que es porque Synchronize es para sincronizar entre hilos y que no habia que usarlo para todo y despues de algunos cambios ya fue. Ahora me encuentro con otro problema, necesito pasar variables desde donde creo el hilo hasta el execute y que dichas variables esten accesibles en ambos sitios. No puedo usar variables globales. ¿Como le puedo pasar variables al hilo? Con THilo hilo = new *THilo() solo puedo pasarle el estado al crearse. Probé a pasarle mas variables modificandola en la clase y me daba un error sobre que estaba haciendo una funcion abstracta o algo asi.
|
Ahora me encuentro con otro problema, tengo usa serie de funciones en unit1 y quiero ejecutarlas desde el hilo pero por supuesto el hilo no sabe ni que existen ¿como hago para poder ejecutarlas desde el hilo?
|
Cita:
Saludos. |
No me funciona o no se como hacerlo. Tengo esto en el Execute del hilo:
Código:
case EXCEPTION_SINGLE_STEP:y en el .h donde están las funciones tengo esto: Código:
#include <vcl.h>En lo que pongo arriba no me reconocería ni FuncSingleStep, ni FuncSingleStep(), ni OnSingleStep(&DebugEv) pero me pasa igual con todas las demás. He probado cosas como: Synchronize(dwContinueStatus = TDebugger::OnExitProcessDebugEvent(&DebugEv)); pero creo que esto no explota de milagro jajaja. Ya no se que probar. |
Se me olvidó decir que el error que da es algo asi:
[C++ Error] THiloDebugger.cpp(67): E2247 'TDebugger::OnExitProcessDebugEvent(_DEBUG_EVENT *)' is not accessible [C++ Error] THiloDebugger.cpp(67): E2283 Use . or -> to call 'TDebugger::OnExitProcessDebugEvent(_DEBUG_EVENT *)' y si pongo en el TDebugger en el private esto: friend class THiloDebugger; desaparece el primer error pero el segundo no y tampoco se si lo que hago de poner friend es algo bueno o no porque lo acabo de descubrir buscando informacion al respecto y ademas me sigue quedando el segundo error que no se como solucionarlo. |
Con lo que pones es difícil entender lo que te pasa. Ten en cuenta que Synchronize admite como parámetro un puntero a una función miembro de tu TThread:
Código:
void __fastcall Synchronize(TThreadMethod &Method);Saludos. |
1 Archivos Adjunto(s)
Adjunto el proyecto y decir que el problema lo tengo en THiloDebugger y que en TDebugger puse en el private "friend class THiloDebugger" para poder acceder a las funciones private del TDebugger desde el THiloDebugger. Ya digo que estoy dando palos de ciego porque no encuentro info al respecto y lo que encuentro no estoy seguro que sea lo que necesito. Si teneis algun pdf donde se hable del manejo de hilo avanzado en C++builder para aprender y me lo pasaseis me hariais un gran favor porque en este tema estoy muy muy verde :o
|
Sin profuncizar mucho en tu código veo errores de bulto. Por ejemplo:
Código:
void __fastcall THiloDebugger::OnCreateThreadDebugEventThread()El mismo error se repite varias veces. Piensa que necesitas hacer para diseñar las clases. Un TThread no es mas que otra clase y se rige por los mismos principios. Si vas a acceder a objetos o variables desde distintos threads al mismo tiempo ten en cuenta que escrituras simultáneas pueden corromper los hilos, de aquí que exista Synchronize. Las API de Windows suelen ser thread-safe pero la VCL no. Espero haberte orientado. Saludos. |
pero en el loop uso Synchronize(OnCreateThreadDebugEventThread); para ejecutar el metodo que has puesto y en la clase TDebugger tengo puesto friend class THiloDebugger que se supone eso me daría acceso a las funciones privadas de la clase TDebugger desde la clase THiloDebugger ¿no? ¿entonces como lo hago?
|
No puedes invocar una función no estática con el nombre de la clase, sino a través de un objeto, por muy amiga que sea otra clase.
Soluciona ese punto antes de buscar más errores. Saludos. |
y entonces ¿Tengo que crear un objeto de tipo TDebugger dentro del THiloDebugger? ¿O como se hace eso?
|
Exacto.
Saludos. |
¿Y da igual que el TDebugger que cree en THiloDebugger no sea el que realmente está en Unit1? ¿Solo lo creo al principio del evento execute y lo elimino al final y simplemente lo uso para ejecutar sus funciones? El siguiente problema seria con los punteros a funciones que están en protected y que no son accesibles desde el objeto como por ejemplo funcexceptionbreakpoint (o algo asi era que lo digo de cabeza desde el movil) ¿Como accedo a eso desde fuera de la clase TDebugger?
|
Cita:
Cita:
Cita:
Saludos. |
ok amigo mil gracias, hare lo que me indicas y ya te cuento como me va.
|
Pues acabo de probar lo siguiente.
En el constructor del hilo he puesto esto: Código:
__fastcall THiloDebugger(bool CreateSuspended, STARTUPINFO *startupInfo, TList *ListBPs, AnsiString Path, PROCESS_INFORMATION *processInfo, CONTEXT *context, DWORD *LastExcepAddress, TDebugger *Debugger);En el protected del THiloDebugger he añadido esto: Código:
TDebugger *Dbg;Código:
Dbg = Debugger;Código:
HiloDbg = new THiloDebugger(true, &si, ListaBPs, PathFile, &pi, &con, &LastExceptionAddress, this);Código:
void __fastcall THiloDebugger::OnCreateThreadDebugEventThread()Código:
[C++ Error] THiloDebugger.cpp(217): E2316 'OnExitDebugEvent' is not a member of 'TDebugger' |
Vale, esto ya compila y corre y lanza el depurador y solo me falta un detalle. He creado esto:
En el protected del THiloDebugger: TEventDebugCallBack FuncEventos; En el Execute: Synchronize(GetFuncEvents); Este es el metodo: Código:
void __fastcall THiloDebugger::GetFuncEvents() |
Hola aguml.
Por favor, no olvides usar las etiquetas [code] tu_codigo [/code] cuando pongas código C++ en el mensaje. Saludos :) |
perdon, me di cuenta tarde de que se me olvidó y lo intente editar pero mo me aparecia la opcion de encapsular al editarlo y no cai en hacerlo manualmente poniendo las etiquetas a mano.
|
Bueno al final lo he conseguido solucionar.
Gracias amigos. |
| La franja horaria es GMT +2. Ahora son las 10:27:49. |
Powered by vBulletin® Version 3.6.8
Copyright ©2000 - 2026, Jelsoft Enterprises Ltd.
Traducción al castellano por el equipo de moderadores del Club Delphi