Página 1 de 1
hb_threadStart()
Enviado: 21 Dez 2011 19:12
por asimoes
Senhores,
Estou testando a função hb_threadStart() para implementar em uma rotina, que deverá testar se a aplicação entrará em manutenção.
Uma vez iniciado o hb_threadStart, tem como dar uma pausa ou parar, para executar um procedimento e depois reinicia-lo?
A função de manutenção será verificada a cada 60 segundos ou definida por variável.
Código: Selecionar todos
FUNCTION MAIN
nTask:=hb_threadStart(@Manutencao()) //hb_threadStart( @DisplayTime())
cTeste:=Space(20)
@10,00 GET cTeste
READ
RETURN Nil
function Manutencao
STATIC nTime
IF nTime = Nil
nTime:=Seconds()
ENDIF
IF Seconds() - nTime >= 60
//Parar o hb_threadStart() aqui
DO WHILE .T.
//faz a manutenção e sai
ENDDO
//Reiniciar o hb_threadStart() aqui
nTime:=Seconds()
ENDIF
RETURN .T.
hb_threadStart()
Enviado: 23 Dez 2011 20:41
por asimoes
Olá a todos,
Pelo jeito ninguém se aventurou com as threads do harbour.
A documentação é quase nula sobre o assunto, mas fico na esperança de alguém saber algo mais.
[]´s
hb_threadStart()
Enviado: 23 Dez 2011 21:44
por Pablo César
Oi Alexandre, eu lamentavelmente ainda sou muito novo neste mundo de 32 bits... rsrs mas para não dizer que não contribuí em nada, achei este exemplo:
http://harbour-devel.1590103.n2.nabble. ... 59316.html. Espero que você consiga outros exemplos com outros colegas, boa sorte !
hb_threadStart()
Enviado: 23 Dez 2011 21:58
por Pablo César
Um observação interessante, talvez válida para ser verificada a sua finalidade. Mas em exemplos na contrib do próprio Harbour, exemplos xbpqtc.prg e demoxbp.prg existe a mesma redefinição para essa função:
#ifdef __XPP__
..//..
FUNCTION Hb_ThreadStart() ; RETURN NIL
..//..
#endif
Isto significa que não funciona com Alaska ??
hb_threadStart()
Enviado: 24 Dez 2011 08:26
por asimoes
Pois é Pablo,
Infelizmente os exemplos não ajudaram.
O que eu quero é o seguinte:
Iniciar a thread
parar a thread - depois de um tempo pré-definido parar athread para não ser chamada novamente, fazer uma operação de processamento e;
reinicrar a thread
hb_threadStart()
Enviado: 24 Dez 2011 09:49
por asimoes
Pessoal,
Descubri uma coisa interessante na thread na função MarcaTela() o quit para a chamada da função.
A impressão que eu tenho é como se fosse um programa a function MarcaTela, enquanto não tem o quit ela fica sendo chamada.
Alguém me corrija se estiver errado.
Código: Selecionar todos
#include "achoice.ch"
#include "inkey.ch"
#include "hbthread.ch"
static aNomes:={}
PROCEDURE Main()
LOCAL aStruct := { ;
{ "Codigo", "C", 2, 0 }, ;
{ "Nome" , "C", 30, 0 }, ;
{ "Idade" , "C", 2, 0 } ;
}
PUBLIC aNomes:={}, nIdle, thID
SET CURSOR ON
CLS
thID := hb_threadStart( @MarcaTela())
ConfiguraAmbiente()
DbCreate( "Teste", aStruct, "DBFCDX", .T., "Teste" )
USE Teste //EXCLUSIVE
INDEX ON Nome TAG Ind01 TO Ind100
SET INDEX TO Ind100
SET ORDER TO TAG Ind01
DBAPPEND()
REPLACE Nome WITH "BELEM"
//--------------------------------------------------------
DBAPPEND()
REPLACE Nome WITH "JOAO"
//--------------------------------------------------------
DBAPPEND()
REPLACE Nome WITH "MARIANA"
//--------------------------------------------------------
DBAPPEND()
REPLACE Nome WITH "BETE"
//--------------------------------------------------------
DBAPPEND()
REPLACE Nome WITH "ELISABETE"
//--------------------------------------------------------
DBAPPEND()
REPLACE Nome WITH "ALEXANDRE"
//--------------------------------------------------------
DBAPPEND()
REPLACE Nome WITH "PEDRO"
//--------------------------------------------------------
DBAPPEND()
REPLACE Nome WITH "RIO DE JANEIRO"
DBGOTOP()
lPrimeira:=.T.
DO WHILE OrdWildSeek("*R*",IF(lPrimeira,.F.,.T.))
AADD(aNomes,TESTE->Nome)
lPrimeira:=.F.
ENDDO
k:=0
DO WHILE K == 0
ACHOICE(02,01,10,30,aNomes,.T.,"funact")
exit
K:=INKEY()
ENDDO
USE
SET CURSOR ON
RETURN
FUNCTION FUNACT(nMode,nElement,nRow)
LOCAL nKey := LastKey()
LOCAL nRet := AC_CONT
LOCAL cMsg
DO CASE
CASE nMode == AC_IDLE
// do some idle processing
//DispOutAt( MaxRow(), 0, Padr(cMsg, MaxCol()+1), "W+/R" )
CASE nMode == AC_EXCEPT
// key handling for unknown keys
IF nKey == K_ESC
nRet := AC_ABORT
ELSEIF nKey == K_RETURN .OR. nKey == K_LDBLCLK
nRet := AC_SELECT
ELSEIF nKey > 31 .AND. nKey < 255
//nRet := AC_GOTO
ENDIF
ENDCASE
RETURN nRet
FUNCTION ConfiguraAmbiente()
Request HB_LANG_PT
Request HB_CODEPAGE_PT850
HB_SETCODEPAGE( "PT850" )
SET CENTURY ON
SET DATE BRITISH
SET EPOCH TO 2000
SET DELETE ON
SET EXCLUSIVE OFF
SET DBFLOCKSCHEME TO 2 // PARA USO JUNTO COM O CLIPPER
SET OPTIMIZE ON
REQUEST DBFCDX
RDDSETDEFAULT("DBFCDX")
DbSetDriver("DBFCDX")
RETURN NIL
FUNCTION MarcaTela()
STATIC nTime
IF nTime = Nil
nTime:=Seconds()
ENDIF
WHILE .T.
IF Seconds()-nTime >= 10
hb_idleSleep(0.030)
ScreenMark("E","R+/N",.F.,.T.)
@22,00 say Time()
@23,00 Say Roda()
nTime:=Seconds()
EXIT
ENDIF
ENDDO
QUIT
RETURN Nil
FUNCTION Roda
STATIC nRoda
IF nRoda = Nil
nRoda:=0
ENDIF
cBarra:="|/-\"
nRoda++
cRoda:=SUBST(cBarra,nRoda,1)
IF nRoda = 4
nRoda:=0
ENDIF
RETURN cRoda
hb_threadStart()
Enviado: 24 Dez 2011 16:44
por Eolo
Asimoes, já andei testando isso, mas no xHarbour.
Quem sabe vc acha as funções por semelhança nos nomes:
StartThread() - inicia um novo thread
StopThread() - termina um thread (quem sabe hb_threadStop?)
ThreadSleep() - Põe um thread pra "dormir" (quem sabe hb_threadSleep?)
hb_threadStart()
Enviado: 26 Dez 2011 18:03
por asimoes
É comandante Eolo,
Obrigado pelas suas dicas, eu já havia visto essa informação.
Resolvi o problema usando hb_IdleAdd() e hb_IdleDel(), que foi até mais fácil.
A própria ShowTime da CT3 usa estas funções.
[]´s
hb_threadStart()
Enviado: 26 Dez 2011 20:55
por marcos.gurupi
Vc poderia colocara qui como ficou. Soh para documentar.
Marcos Roberto.
hb_threadStart()
Enviado: 27 Dez 2011 07:48
por asimoes
marcos.gurupi escreveu:Vc poderia colocara qui como ficou. Soh para documentar.
Marcos, eu me baseei pelo exemplo da showtime veja o código:
Código: Selecionar todos
#include "common.ch"
FUNCTION SHOWTIME( nRow, nCol, lNoSec, cColor, l12, lAmPm )
THREAD STATIC t_hTimer := NIL
IF ISNUMBER( nRow ) .AND. nRow >= 0 .AND. nRow <= MAXROW( .T. )
IF t_hTimer != NIL
HB_IDLEDEL( t_hTimer )
ENDIF
t_hTimer := HB_IDLEADD( {|| _HB_CTDSPTIME( nRow, nCol, lNoSec, cColor, ;
l12, lAmPm ) } )
ELSEIF t_hTimer != NIL
HB_IDLEDEL( t_hTimer )
t_hTimer := NIL
ENDIF
RETURN ""
Meu programinha de teste para implementar minha rotina de verificação de manutenção mais abrangente.
Código: Selecionar todos
#include "inkey.ch"
#include "hbthread.ch"
#include "common.ch"
STATIC lEspera:=.F.
STATIC vGet
THREAD STATIC t_hIdle
FUNCTION MAIN
t_hIdle:=hb_idleadd( {|| ChecaManutencao(60)})
MonitorMain()
RETURN Nil
FUNCTION MONITORMAIN
MONITOR()
QUIT
RETURN NIL
FUNCTION MONITOR
LOCAL GetList:={}, cNome:="TESTE ", cSN:=" "
@12,00 SAY "ESPERANDO MENSAGEM DE MANUTENۂO : " GET cNome VALID PegaGet() //Valid lEspera = .T.
@13,00 SAY "CONFIRMA SAIDA (S/N) : " GET cSN VALID cSN $ "SN"
READ
RETURN Nil
FUNCTION PegaGet
vGet:=GetActive()
cVar:=vGet:VarGet(vGet)+"1"
vGet:VarPut(cVar)
vGet:UpdateBuffer()
RETURN .T.
FUNCTION ChecaManutencao(nTempo)
STATIC nTime
IF nTime = Nil
nTime:=Seconds()
ENDIF
IF Seconds()-nTime > nTempo
nTime:=Seconds()
IF SistemaEmManutencao()
Alert("O sistema entrar em manuten‡Æo, favor fecha-lo!")
//hb_idleDel( t_hIdle ) //Se quiser terminar a chamada da thread use essa fun‡Æo.
//t_hIdle := NIL
ENDIF
ENDIF
//hb_idleSleep(0.1) //Usando esta fun‡Æo aumenta o consumo de CPU
RETURN Nil
FUNCTION SistemaEmManutencao
IF SELECT("SISTEMA") = 0
USE SISTEMA ALIAS SISTEMA SHARED NEW
ENDIF
RETURN SISTEMA->EmManut
INIT FUNCTION ConfiguraAmbiente()
REQUEST HB_LANG_PT
REQUEST HB_CODEPAGE_PT850
HB_SETCODEPAGE( "PT850" )
SET CENTURY ON
SET DATE BRITISH
SET EPOCH TO 2000
SET DELETE ON
SET EXCLUSIVE OFF
SET DBFLOCKSCHEME TO 2 // PARA USO JUNTO COM O CLIPPER
SET OPTIMIZE ON
REQUEST DBFCDX
RDDSETDEFAULT("DBFCDX")
DbSetDriver("DBFCDX")
SET CURSOR ON
CLS
RETURN NIL