hb_threadStart()

Projeto [x]Harbour - Compilador de código aberto compatível com o Clipper.

Moderador: Moderadores

Avatar do usuário
asimoes
Colaborador
Colaborador
Mensagens: 4919
Registrado em: 26 Abr 2007 16:48
Localização: RIO DE JANEIRO-RJ

hb_threadStart()

Mensagem 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.
►Harbour 3.x | Minigui xx-x | HwGui◄
Pense nas possibilidades abstraia as dificuldades.
Não corrigir nossas falhas é o mesmo que cometer novos erros.
A imaginação é mais importante que o conhecimento. (Albert Einstein)
Avatar do usuário
asimoes
Colaborador
Colaborador
Mensagens: 4919
Registrado em: 26 Abr 2007 16:48
Localização: RIO DE JANEIRO-RJ

hb_threadStart()

Mensagem 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
►Harbour 3.x | Minigui xx-x | HwGui◄
Pense nas possibilidades abstraia as dificuldades.
Não corrigir nossas falhas é o mesmo que cometer novos erros.
A imaginação é mais importante que o conhecimento. (Albert Einstein)
Avatar do usuário
Pablo César
Usuário Nível 7
Usuário Nível 7
Mensagens: 5312
Registrado em: 31 Mai 2006 10:22
Localização: Curitiba - Paraná

hb_threadStart()

Mensagem 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 !
Um clip-abraço !

Pablo César Arrascaeta
Compartilhe suas dúvidas e soluções com todos os colegas aqui do fórum.
Evite enviar as dúvidas técnicas por MPs ou eMails, assim todos iremos beneficiar-nos.
Avatar do usuário
Pablo César
Usuário Nível 7
Usuário Nível 7
Mensagens: 5312
Registrado em: 31 Mai 2006 10:22
Localização: Curitiba - Paraná

hb_threadStart()

Mensagem 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 ??
Um clip-abraço !

Pablo César Arrascaeta
Compartilhe suas dúvidas e soluções com todos os colegas aqui do fórum.
Evite enviar as dúvidas técnicas por MPs ou eMails, assim todos iremos beneficiar-nos.
Avatar do usuário
asimoes
Colaborador
Colaborador
Mensagens: 4919
Registrado em: 26 Abr 2007 16:48
Localização: RIO DE JANEIRO-RJ

hb_threadStart()

Mensagem 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
►Harbour 3.x | Minigui xx-x | HwGui◄
Pense nas possibilidades abstraia as dificuldades.
Não corrigir nossas falhas é o mesmo que cometer novos erros.
A imaginação é mais importante que o conhecimento. (Albert Einstein)
Avatar do usuário
asimoes
Colaborador
Colaborador
Mensagens: 4919
Registrado em: 26 Abr 2007 16:48
Localização: RIO DE JANEIRO-RJ

hb_threadStart()

Mensagem 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
►Harbour 3.x | Minigui xx-x | HwGui◄
Pense nas possibilidades abstraia as dificuldades.
Não corrigir nossas falhas é o mesmo que cometer novos erros.
A imaginação é mais importante que o conhecimento. (Albert Einstein)
Avatar do usuário
Eolo
Colaborador
Colaborador
Mensagens: 1134
Registrado em: 08 Dez 2005 18:24
Localização: São Paulo - SP

hb_threadStart()

Mensagem 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?)
Avatar do usuário
asimoes
Colaborador
Colaborador
Mensagens: 4919
Registrado em: 26 Abr 2007 16:48
Localização: RIO DE JANEIRO-RJ

hb_threadStart()

Mensagem 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
►Harbour 3.x | Minigui xx-x | HwGui◄
Pense nas possibilidades abstraia as dificuldades.
Não corrigir nossas falhas é o mesmo que cometer novos erros.
A imaginação é mais importante que o conhecimento. (Albert Einstein)
marcos.gurupi
Usuário Nível 4
Usuário Nível 4
Mensagens: 939
Registrado em: 06 Jul 2004 11:53
Localização: Gurupi-TO

hb_threadStart()

Mensagem por marcos.gurupi »

Vc poderia colocara qui como ficou. Soh para documentar.

Marcos Roberto.
Marcos Roberto
NetService Software
Avatar do usuário
asimoes
Colaborador
Colaborador
Mensagens: 4919
Registrado em: 26 Abr 2007 16:48
Localização: RIO DE JANEIRO-RJ

hb_threadStart()

Mensagem 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
►Harbour 3.x | Minigui xx-x | HwGui◄
Pense nas possibilidades abstraia as dificuldades.
Não corrigir nossas falhas é o mesmo que cometer novos erros.
A imaginação é mais importante que o conhecimento. (Albert Einstein)
Responder