Todo lo bueno tiene un final, y esta serie sobre threads en Harbour llega a su fin.
Espero que os haya sido ameno y entrenido, tanto como yo en escribirlo.
Es importante ver los ejemplos de Harbour, son muy ilustrativos , aunque para los que no estamos acostumbrados, pueden ser un poco lioso al inicio
Listado de ejemplos de Harbour
harbour/contrib/mt/mttest1.prg
- Muestra el uso como detached local y valores complejos usando un thread
harbour/contrib/mt/mttest2.prg
- Muestra el uso del comando QUIT y el estamento ALWAYS en ejecución. El thread hijo usa QUITt antes que el principal
harbour/contrib/mt/mttest3.prg
- Muestra el uso del comando QUIT y el estamento ALWAYS en ejecución. El thread main usa QUITt antes que el thread hijo
harbour/contrib/mt/mttest4.prg
- Muestra el uso de variables protegidas y sin proteger
harbour/contrib/mt/mttest5.prg
- Muestra el uso thread static variables
harbour/contrib/mt/mttest6.prg
- Usando variables tipo memvar con hilos
harbour/contrib/mt/mttest7.prg
- Ejemplo de uso de Mutex para enviar/recibir mensajes entre hilos.
harbour/contrib/mt/mttest8.prg
- Usando el compartir variables de memoria entre hilos
harbour/contrib/mt/mttest9.prg
- Muestra como usar el mismo alias entre distintos hilos, usando estas 2 funciones hb_dbRequest y hb_dbDetach.
- Nota: Un regalo de despedida lo tenéis abajo ;-)
harbour/contrib/mt/mttest10.prg
- Muestra una consola por thread mostrando un browse
harbour/contrib/mt/mttest11.prg
- Muestra un ejemplo de un thread asincrono mostrando un reloj
harbour/contrib/mt/mttest12.prg
- Variables a nivel de hilo, pueden ser declaradas como;
THREAD STATICt_Var1
Esta variable es una variable static por cada hilo creado.
Mención especial para el código fuente /contrib/httpd/core.prg, donde podemos ver muchas de estas técnicas explicadas.
De regalo ;-)
Esto fue escrito hace ya 6 años para un sistema para hacer una indexación multihilo, aunque en la mayoría de los casos existe penalización por tema de velocidad de disco, es bueno saber COMO se podria hacer.
En más de 1000 servidores diferentes hemos encontrado que un máxima de 5 hilos por
tabla y un índice a la vez, la ganancia es sustancial en un sistema monolítico.
/*
Example multiThreads index.
One thread by table , and one thread by index.
2010 Rafa Carmona
Thread Main
|---------> Thhread child table for test.dbf
| |----> Thread child index fname
| |
| |----->Thread child index fcode
|
|---------> Thhread child table for test2.dbf
|----->Thread child index fname2
*/
#include "hbthread.ch"
proc Main( uCreate )
Local nSeconds
Local aFiles := { "test", "test2" } // Arrays files dbf
Local aNtx := { { "fname", "fcode" },; // files index for test
{ "fName2" } } // files index for test2
Local aExpr := { { "name", "code" },;
{ "dtos(fecha)+str(code)" } } // Expresions
Local cDbf
if empty( lCreate )
lCreate := "0"
endif
setmode( 25,80 )
cls
if uCreate = "1"
? "Create test.dbf and test2.dbf"
dbCreate("test",{ {"name","C",1,0 },{"code","N",7,0 } } )
use test
while lastRec() < 1000000
dbAppend()
field->name := chr( recno() )
field->code := recno()
enddo
close
dbCreate("test2",{ {"fecha","D",8,0 },{"code","N",7,0 } } )
use test2
while lastRec() < 1000000
dbAppend()
field->fecha := date() + recno()
field->code := recno()
enddo
close
endif
cls
// Threads
nSeconds := Seconds()
for each cDbf in aFiles
? "Process.: " + cDbf
hb_threadStart( @aCreateIndexe(), cDbf, aNtx[ cDbf:__enumindex ],
aExpr[ cDbf:__enumindex ], cDbf:__enumindex )
next
? "Wait for threads ...."
hb_threadWaitForAll()
? hb_valTostr( Seconds() - nSeconds )
? "finish"
return
function aCreateIndexe( cFile, aNtx, aExpr, nPosDbf )
Local nContador := 1
Local cFileNtx, cExpr
Local nLong := Len( aNtx )
Local aThreads := {}
Local cAlias
use ( cFile )
cAlias := alias()
hb_dbDetach( cAlias ) // Libero el alias
for each cFileNtx in aNtx
cExpr := aExpr[ cFileNtx:__enumindex ]
nContador := 1
nPos := cFileNtx:__enumindex
aadd( aThreads, hb_threadStart( @crea(), cAlias,cExpr,
cFileNtx, nPos, nPosDbf ) )
next
aEval( aThreads, { |x| hb_threadJoin( x ) } ) // wait threads childs
hb_dbRequest( cAlias, , , .T.) // Restaura el alias
close
RETURN NIL
proc crea( cAlias, cExpr, cFileNtx, nPos, nPosDbf )
Local nContador := 1
hb_dbRequest( cAlias, , , .T.) // Restaura el alias
INDEX ON &(cExpr) TO &(cFileNtx) ;
EVAL {|| hb_dispOutAt( nPosDbf, iif( nPos = 1, 20, 40 ),
alltrim( hb_valtostr( nContador) ), "GR+/N" ), nContador += INT(
LASTREC() / 100 ) , .T. } ;
EVERY INT( LASTREC() / 100 )
hb_dbDetach( cAlias ) // Libera el alias
return
|
No hay comentarios:
Publicar un comentario