Page 1 of 1

Soporte Multithread en xHarbour

PostPosted: Wed Feb 10, 2010 5:09 pm
by Salvador
¿Alguien ha probado el soporte multithread en Xharbour?. ¿Es robusto y estable?.
Estoy pensando en migrar un proyecto con sockets de FWH a sockets de xHarbour con multithreads pero quisiera estar seguro de no encontrar problemas antes de iniciarlo.

Agradezco opiniones.

Re: Soporte Multithread en xHarbour

PostPosted: Thu Feb 11, 2010 7:53 am
by anserkk
Mr.Salvador,

He intentado multithreading utilizando xHarbour y Borland, pero la aplicación se bloquea.

Por favor, revise el hilo por debajo de determinado.

http://forums.fivetechsupport.com/viewtopic.php?f=3&t=18008&start=15#p94458

Anser

Re: Soporte Multithread en xHarbour

PostPosted: Thu Feb 11, 2010 10:28 am
by Antonio Linares
Salvador,

En la misma conversación que te indica Anser, revisa esto:

viewtopic.php?p=94639#p94639

Re: Soporte Multithread en xHarbour

PostPosted: Thu Feb 11, 2010 11:19 pm
by Salvador
Si no entiendo mal, el multithreading con Harbour y parte de FWH funciona, pero Harbour no tiene soporte para sockets, o me equivoco?.

Re: Soporte Multithread en xHarbour

PostPosted: Sun Feb 14, 2010 11:31 am
by Salvador
Antonio,

¿Se puede con Harbour incluir objetos de FWH como TSocket o Ttimer dentro de un thread?

Re: Soporte Multithread en xHarbour

PostPosted: Sun Feb 14, 2010 3:22 pm
by Antonio Linares
Salvador,

Por lo visto la limitación que impone Windows para el uso de threads es que los mensajes de Windows han de procesarse en el mismo thread en donde se haya creado la ventana. De no seguir esta regla se producirían GPFs propios de Windows.

En caso de ser asi, hay que prestar atención a no procesar ningun mensaje de Windows en un thread distinto al thread principal, suponiendo que en el thread principal se haya creado la ventana.

Tanto TSocket como TTimer hacen que Windows envie mensajes a la ventana, mensajes que hay que procesar en el mismo thread de la ventana. Es por esto que te comento lo anterior :-)

Nosotros aun no hemos probado este tipo de código, pero supuestamente si queremos procesar mensajes en un thread, entonces la ventana que reciba los mensajes ha de ser creada en ese mismo thread.

Re: Soporte Multithread en xHarbour

PostPosted: Sun Feb 14, 2010 8:33 pm
by Salvador
Este código:
Code: Select all  Expand view
function Main()
Local  oWnd
 
    PUBLIC oApp
   
   DEFINE WINDOW oWnd
   
   ACTIVATE WINDOW oWnd MAXIMIZED;
   ON INIT  ( oApp := Tapp():New( oWnd ),  StartThread(@StartServer(), oApp), WaitForThreads() )  ;

return nil

procedure StartServer(oApp )
local oSocket
LOCAL pMutex   := HB_MutexCreate()

oSocket = TSocket():New( 8083 )
oApp:oSocket := oSocket
oSocket:bAccept := { || StartThread( {|| Tserver():New( TSocket():Accept( oSocket:nSocket ), pMutex, oApp  )} ) }
oSocket:Listen()
LogFile( "thread.log",{"Inicia Server Thread: ", Str( GetSystemThreadID() )} ) // thread 2

return


El objeto creado en el Thread 2 sus método se ejecutan en el TH 1.

En qué ámbito hay que crearlo para que se ejecute en el TH2 ?

Re: Soporte Multithread en xHarbour

PostPosted: Sun Feb 14, 2010 8:54 pm
by Antonio Linares
Salvador,

Ese código te funciona bien ?

En caso de que no te funcionase, prueba a crear la ventana desde la misma función en donde creas el socket.

Re: Soporte Multithread en xHarbour

PostPosted: Mon Feb 15, 2010 12:21 am
by Salvador
Si funciona perfecto, pero GetSystemThreadID() llamado desde el objeto siempre retorna 1 a pesar de que hay varios objetos creados al mismo tiempo, por lo que parece que el objeto no se ejecuta desde un nuevo thread cada vez.

Re: Soporte Multithread en xHarbour

PostPosted: Mon Feb 15, 2010 10:27 pm
by Salvador
Si creamos un objeto sin asignarlo a una variable , ¿como se libera la memoria que utiliza una vez este finaliza su ejecución?. En su metodo End() se puede hacer algo así:
Code: Select all  Expand view

METHOD End()  
self := nil
return nil 

Lo he probado, no genera ningún error, pero realmente no se si es correcto hacerlo de este modo.

Re: Soporte Multithread en xHarbour

PostPosted: Tue Feb 16, 2010 8:14 am
by Antonio Linares
Salvador,

No es necesario hacer nada. El recolector de basuras lo destruye automaticamente una vez ya no esté en uso, es decir, no esté guardado en una variable estática, elemento de un array, etc.

La forma de llamar al recolector de basuras es usando hb_gcAll(). FWH lo llama automaticamente cuando se sale desde un diálogo.

Re: Soporte Multithread en xHarbour

PostPosted: Tue Feb 16, 2010 6:57 pm
by Salvador
De eso hablo de crearlo sin asignarlo a ninguna variable, ejemplo:

Code: Select all  Expand view
Function Main()
local oWnd

    DEFINE WINDOW oWnd  

    ACTIVATE WINDOW oWnd;
    ON INIT Tobjeto():New(oWnd)

return nil

CLAS Tobjeto
METHOD New(oWnd)
METHOD End()
ENDCLASS

METHOD New(oWnd) CLASS Tobjeto
local oTimer    := Ttimer():New( 3000, { || ::End() }, oWnd)
oTimer:Activate()
return self

METHOD End() CLASS Tobjeto
hb_gcall()
return nil

Se auto destruye ?

Re: Soporte Multithread en xHarbour

PostPosted: Tue Feb 16, 2010 7:23 pm
by Daniel Garcia-Gil
Salvador...

si se "autodestruye"... cuando cierras la ventana, envias un mensaje WM_CLOSE a la misma, este mensaje es capturado por FW para llamar al metodo destroy que a su vez "mata" todos los controles hijos que le pertenescan, window se encarga de enviar el mismo mensaje (WM_CLOSE) a sus hijos, en este caso elimina el timer que tienes activo sin necesidad que llames a "END" propio del timer

Re: Soporte Multithread en xHarbour

PostPosted: Tue Feb 16, 2010 10:06 pm
by Salvador
Gracias Daniel, queda claro.
Pero creando una CLASSDATA {} y añadiendo cada objeto creado, después pueden ser eliminados desde la misma clase liberando la memoria ¿no?

Re: Soporte Multithread en xHarbour

PostPosted: Tue Feb 16, 2010 10:10 pm
by Antonio Linares
Salvador,

Code: Select all  Expand view

    ACTIVATE WINDOW oWnd;
    ON INIT Tobjeto():New(oWnd)
 

En ese código estás guardando el objeto dentro de un codeblock, y hasta que ese codeblock no se limpiase (porque su objeto contenedor a su vez se limpie) el objeto sigue existiendo.