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
return
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 nil
cnavarro 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
Return to FiveWin for Harbour/xHarbour
Users browsing this forum: nageswaragunupudi and 44 guests