Hi,
Does anyone have an example of using WorkAreas and MT?
Hi,
Does anyone have an example of using WorkAreas and MT?
/*
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
returnUn ejemplo muy bueno que habrá que guardar como "oro en paño"
Gracias Rafa
Rafa,
It is possible for one thread to use more than one workarea?
Function Main()
Open table "customers" alias "customer"
Go Top
hb_threadStart( @create_child_thread() )
? customer->recno() // First
hb_threadWaitForAll()
return
function create_child_thread()
Open table "customers" alias "customer"
Open table "telephone" alias "telephone"
Select "customer" // This work area NOT IS function main
go bottom
? customer->recno() // Last
CLOSE ALL
return nilcnavarro wrote:Un ejemplo muy bueno que habrá que guardar como "oro en paño"
Gracias Rafa
#define N_THREADS 5
STATIC s_num_procesos
Function main()
aDbfs := { .... tus dbf ... }
while nPosTable <= nLen_Table
if ( nTecla := inkey() ) = K_ESC
exit
endif
// No se ha muerto ningun proceso , loop
if N_THREADS = s_num_procesos
loop
endif
cDbf := aDbfs[ nPosTable ]
s_num_procesos++
hb_threadStart( @aCreateIndexe(), cDbf, aNtxs[ nPosTable ],
aKeys[ nPosTable ], aFor[ nPosTable ] )
nPosTable++
end while
hb_threadWaitForAll() // Esperamos a los ultimos.
return
function aCreateIndexe( cFile, aNtx, aExpr, aFor )
... codigo....
hb_mutexLock( s_hMutex )
s_num_procesos--
hb_mutexUnLock( s_hMutex )
return nil
Cuando el hilo muere, se decrementamos el numero de proceso, dando lugar
a que el bucle principal pueda procesar un nuevo hilo.
El problema que tenia es que tenia 5 hilos, y cada uno de ellos pinta en
un lugar de la pantalla, y claro, adivinar donde tiene que pinta era más
complicado que esto
Rafa, cualquier codigo que compartas me será de gran ayuda
Llevo tiempo queriendo meterme en este tema, pero la informacion encontrada no me era suficiente.