Clipper On Line • Ver Tópico - Duvida sobre Thread (Hb_ThreadStart)

Duvida sobre Thread (Hb_ThreadStart)

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

Moderador: Moderadores

 

Duvida sobre Thread (Hb_ThreadStart)

Mensagempor asimoes » 23 Fev 2021 11:31

Tenho esse teste com uma Thread usando os parâmetros HB_BITOR

A função recebe lContinua .T., funciona.

Mas se eu quiser trocar o valor para lContinua := .F., a Thread continua com o valor da variável lContinua com .T.
Tem como intervir nos valores em uma thread?

no DO WHILE lContinua

PUBLIC lContinua := .T.

        nThread := Hb_ThreadStart( HB_BITOR( HB_THREAD_INHERIT_PUBLIC, ;
                                             HB_THREAD_INHERIT_PRIVATE, ;
                                             HB_THREAD_INHERIT_MEMVARS, ;
                                             HB_THREAD_MEMVARS_COPY ), ;
                                   { ||  Teste() } )

lContInua := .F.                                   

FUNCTION Teste()
LOCAL nRow AS NUMERIC, nCol AS NUMERIC

   nCol := Col()
   nRow := Row()
   
   nSeconds := Seconds()
   
   DO WHILE lContinua
   
      Hb_IdleSleep( 1 )

      IF (Seconds() - nSeconds) > 5
         nSeconds := Seconds()
         cTime := Time()
         IF File( "TIME.TXT" )
            cTime := Hb_MemoRead( "TIME.TXT" ) + Hb_Eol() + cTime
         ENDIF
         Hb_MemoWrit( "TIME.TXT" , cTime )
      ENDIF   
      hwg_DoEvents()
   ENDDO
   
   WAPI_BRINGWINDOWTOTOP( Hb_gtInfo( HB_GTI_WINHANDLE ) )
   
   Quit   

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)
Avatar de usuário

asimoes
Colaborador

Colaborador
 
Mensagens: 4919
Data de registro: 26 Abr 2007 16:48
Cidade/Estado: RIO DE JANEIRO-RJ
Curtiu: 341 vezes
Mens.Curtidas: 258 vezes

Duvida sobre Thread (Hb_ThreadStart)

Mensagempor JoséQuintas » 23 Fev 2021 12:07

Não, só se for PUBLIC.

Uma opção é criar classe e/ou função.

FUNCTION AppUserName( cValue )

   STATIC cAppUserName := ""

   IF cValue != Nil
      cAppUserName := cValue
   ENDIF

   RETURN cAppUserName


Desse jeito, usa AppUserName(), ou AppUserName( "JOSE" ), tanto faz a thread.
Acaba sendo bom, porque a compilação vai avisar se escrever errado.

Também pode ser array.
Classe... não é tão bom, porque não vai ter checagem de nome errado.
José M. C. Quintas
Harbour 3.2, mingw, gtwvg, multithread, dbfcdx, ADO+MySql, PNotepad
"The world is full of kings and queens, who blind our eyes and steal our dreams Its Heaven and Hell"

https://github.com/JoseQuintas/
Avatar de usuário

JoséQuintas
Membro Master

Membro Master
 
Mensagens: 18014
Data de registro: 26 Fev 2007 11:59
Cidade/Estado: São Paulo-SP
Curtiu: 15 vezes
Mens.Curtidas: 1206 vezes

Duvida sobre Thread (Hb_ThreadStart)

Mensagempor JoséQuintas » 23 Fev 2021 12:15

Veja se é uma coisa parecida com esta que está querendo:

CREATE CLASS RunWhileThreadClass

   VAR lExit        INIT .F.
   VAR nThreadId
   VAR nInterval    INIT 600
   VAR cWindowTitle INIT ""
   VAR bCode
   METHOD New()     INLINE ::nThreadId := hb_ThreadSelf(), SELF
   METHOD Execute( bCode )

   ENDCLASS

METHOD Execute( bCode ) CLASS RunWhileThreadClass

   LOCAL nCont

   hb_gtReload( "WVG" )
   IF bCode != NIL
      ::bCode := bCode
   ENDIF
   AppInitSets()
   HB_GtInfo( HB_GTI_WINTITLE, ::cWindowTitle )
   wvgSetAppWindow():Hide()
   DO WHILE ! ::lExit
      Eval( ::bCode )
      FOR nCont = 1 TO ::nInterval
         hb_ReleaseCPU()
         IF hb_ThreadWait( ::nThreadId, 0.1, .T. ) == 1
            ::lExit := .T.
         ENDIF
         Inkey(1)
         IF ::lExit
            EXIT
         ENDIF
      NEXT
   ENDDO

   RETURN NIL


O que isso faz?
a thread vai ficar rodando, enquanto a thread que a chamou continuar ativa.
Opcionalmente, se alterar lExit := .T. ela encerra assim que possível.

Exemplo:

oClasse := RunWHileThreadClass():New()
oClasse:bCode := { || Any() }
hbThreadStart( { || oClasse:Execute() } )
...
oClasse:lExit := .T.


Usei isso, por exemplo, em pedidos.
Enquanto o usuário estava na digitação de pedidos, aparecia alerta avisando de atrasos.
Saiu de pedidos, a rotina também encerrava automático. (nesse caso não precisava oClasse:lExit := .T.)

E qualquer coisa da classe, fica visível de qualquer thread.
São assim os controles Windows/GUI, só pra curiosidade.
José M. C. Quintas
Harbour 3.2, mingw, gtwvg, multithread, dbfcdx, ADO+MySql, PNotepad
"The world is full of kings and queens, who blind our eyes and steal our dreams Its Heaven and Hell"

https://github.com/JoseQuintas/
Avatar de usuário

JoséQuintas
Membro Master

Membro Master
 
Mensagens: 18014
Data de registro: 26 Fev 2007 11:59
Cidade/Estado: São Paulo-SP
Curtiu: 15 vezes
Mens.Curtidas: 1206 vezes

Duvida sobre Thread (Hb_ThreadStart)

Mensagempor JoséQuintas » 23 Fev 2021 12:20

O cuidado com threads sobre compartilhar variáveis é grande.

Imagine o usuário num relatório escolhendo impressora, e em outro lugar também escolhendo impressora.
Se a variável for pública, um relatório vai alterar a impressora do outro.

Outro caso, um array:
Uma thread tá trabalhando com o array de um tamanho, e a outra thread altera esse tamanho.
E não só array, de repente uma string de tamanho 30 vira tamanho 10... se for no momento exato de pegar o conteúdo, o estrago pode ser grande, porque invade área da memória que não pertence à variável.
Nessas situações é onde precisa um cuidado a mais, o tal Mutex() que seria parecido com RLock(), mas pra variáveis.
Isso evita que o conteúdo seja alterado por outra thread durante o uso.
José M. C. Quintas
Harbour 3.2, mingw, gtwvg, multithread, dbfcdx, ADO+MySql, PNotepad
"The world is full of kings and queens, who blind our eyes and steal our dreams Its Heaven and Hell"

https://github.com/JoseQuintas/
Avatar de usuário

JoséQuintas
Membro Master

Membro Master
 
Mensagens: 18014
Data de registro: 26 Fev 2007 11:59
Cidade/Estado: São Paulo-SP
Curtiu: 15 vezes
Mens.Curtidas: 1206 vezes

Duvida sobre Thread (Hb_ThreadStart)

Mensagempor asimoes » 23 Fev 2021 13:27

QUintas,

Entendi isso é muito pontual, enfim valeu pela dica
â–º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 de usuário

asimoes
Colaborador

Colaborador
 
Mensagens: 4919
Data de registro: 26 Abr 2007 16:48
Cidade/Estado: RIO DE JANEIRO-RJ
Curtiu: 341 vezes
Mens.Curtidas: 258 vezes

Duvida sobre Thread (Hb_ThreadStart)

Mensagempor asimoes » 23 Fev 2021 13:29

Quintas,

faltou a função AppInitSets()
â–º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 de usuário

asimoes
Colaborador

Colaborador
 
Mensagens: 4919
Data de registro: 26 Abr 2007 16:48
Cidade/Estado: RIO DE JANEIRO-RJ
Curtiu: 341 vezes
Mens.Curtidas: 258 vezes

Duvida sobre Thread (Hb_ThreadStart)

Mensagempor JoséQuintas » 23 Fev 2021 13:52

asimoes escreveu:faltou a função AppInitSets()


Uso essa pra configurar meu default.
Em thread precisa configurar RDDSetDefault(), SET DATE, e outras coisas, como se fosse outro EXE.
Então só criar com os seus defaults.

Nota: Usei um nome que achei adequeado, inicia os "sets" do aplicativo, por isso chamei AppInitSets()
José M. C. Quintas
Harbour 3.2, mingw, gtwvg, multithread, dbfcdx, ADO+MySql, PNotepad
"The world is full of kings and queens, who blind our eyes and steal our dreams Its Heaven and Hell"

https://github.com/JoseQuintas/
Avatar de usuário

JoséQuintas
Membro Master

Membro Master
 
Mensagens: 18014
Data de registro: 26 Fev 2007 11:59
Cidade/Estado: São Paulo-SP
Curtiu: 15 vezes
Mens.Curtidas: 1206 vezes

Duvida sobre Thread (Hb_ThreadStart)

Mensagempor asimoes » 23 Fev 2021 16:15

Quintas,

Aproveitando parte da sua classe, consegui simular o que eu queria debugando pra saber o conteúdo do arquivo time.txt
A função teste recebeu a troca da variável lExit depois de executada

CREATE CLASS RunWhileThreadClass

   VAR lExit        INIT .F.
   METHOD New()     INLINE SELF CONSTRUCTOR

   ENDCLASS
   PUBLIC oClasse := RunWHileThreadClass():New()

        nThread := Hb_ThreadStart( HB_BITOR( HB_THREAD_INHERIT_PUBLIC, ;
                                             HB_THREAD_INHERIT_PRIVATE, ;
                                             HB_THREAD_INHERIT_MEMVARS, ;
                                             HB_THREAD_MEMVARS_COPY ), ;
                                             { || Teste() } )

   Inkey(0)
   
   oClasse:lExit := .T.       
   

FUNCTION Teste()
LOCAL nRow AS NUMERIC, nCol AS NUMERIC

   nSeconds := Seconds()
     
   DO WHILE ! oClasse:lExit
   
      Hb_IdleSleep( .1 )

      IF (Seconds() - nSeconds) > 5
         nSeconds := Seconds()
         cTime := Time()
         IF File( "TIME.TXT" )
            cTime := Hb_MemoRead( "TIME.TXT" ) + Hb_Eol() + cTime
         ENDIF
         Hb_MemoWrit( "TIME.TXT" , cTime )
      ENDIF   
      hwg_DoEvents()
   ENDDO

   Quit   

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)
Avatar de usuário

asimoes
Colaborador

Colaborador
 
Mensagens: 4919
Data de registro: 26 Abr 2007 16:48
Cidade/Estado: RIO DE JANEIRO-RJ
Curtiu: 341 vezes
Mens.Curtidas: 258 vezes

Duvida sobre Thread (Hb_ThreadStart)

Mensagempor JoséQuintas » 23 Fev 2021 22:53

Só um comentário:

Porque não uma janela executando alguma coisa?
José M. C. Quintas
Harbour 3.2, mingw, gtwvg, multithread, dbfcdx, ADO+MySql, PNotepad
"The world is full of kings and queens, who blind our eyes and steal our dreams Its Heaven and Hell"

https://github.com/JoseQuintas/
Avatar de usuário

JoséQuintas
Membro Master

Membro Master
 
Mensagens: 18014
Data de registro: 26 Fev 2007 11:59
Cidade/Estado: São Paulo-SP
Curtiu: 15 vezes
Mens.Curtidas: 1206 vezes

Duvida sobre Thread (Hb_ThreadStart)

Mensagempor asimoes » 24 Fev 2021 10:49

JoséQuintas escreveu:Só um comentário:

Porque não uma janela executando alguma coisa?


O meu teste é conseguir debugar o sistema enquanto a thread está sendo executada, dessa forma eu consigo debugar enquanto a thread está rodando e atribuir oClasse:lExit := .T. a qualquer momento no meu teste por fora da thread para interromper a sua execução, nesse teste eu não preciso de janela na thread

O interessante não sei se é uma limitação ou falha só consegui interromper a thread com uma variável de classe, uma variável publica tipo public lExit := .F. e depois de executada a thread modificando para lExit para .f. , não funciona, somente com variável da classe
â–º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 de usuário

asimoes
Colaborador

Colaborador
 
Mensagens: 4919
Data de registro: 26 Abr 2007 16:48
Cidade/Estado: RIO DE JANEIRO-RJ
Curtiu: 341 vezes
Mens.Curtidas: 258 vezes

Duvida sobre Thread (Hb_ThreadStart)

Mensagempor JoséQuintas » 24 Fev 2021 12:02

Se é só por causa da variável, usa a outra opção.

FUNCTION AbortRun( lAbort )

   STATIC sAbort := .F.

   IF lAbort != Nil .AND. lAbort
      sAbort := .T.
   ENDIF

   RETURN sAbort


Na rotina:

DO WHILE .T.
   IF AbortRun()
      EXIT
   ENDIF
ENDDO


E quando precisar:

AbortRun( .F. )
hb_thread(...)
...
AbortRun( .T. )


A não ser que vão ter várias situações diferentes ao mesmo tempo.
José M. C. Quintas
Harbour 3.2, mingw, gtwvg, multithread, dbfcdx, ADO+MySql, PNotepad
"The world is full of kings and queens, who blind our eyes and steal our dreams Its Heaven and Hell"

https://github.com/JoseQuintas/
Avatar de usuário

JoséQuintas
Membro Master

Membro Master
 
Mensagens: 18014
Data de registro: 26 Fev 2007 11:59
Cidade/Estado: São Paulo-SP
Curtiu: 15 vezes
Mens.Curtidas: 1206 vezes

Duvida sobre Thread (Hb_ThreadStart)

Mensagempor asimoes » 24 Fev 2021 13:07

Quintas,

A sua alternativa também resolver, vlw
â–º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 de usuário

asimoes
Colaborador

Colaborador
 
Mensagens: 4919
Data de registro: 26 Abr 2007 16:48
Cidade/Estado: RIO DE JANEIRO-RJ
Curtiu: 341 vezes
Mens.Curtidas: 258 vezes

Duvida sobre Thread (Hb_ThreadStart)

Mensagempor asimoes » 24 Fev 2021 13:29

Aquintas,

Não funcionou

Troquei o oClasse:lExit no while por AbortRun()

Antes da chamada da Thread

AbortRun( .F. )

DO WHILE ! AbortRun() //oClasse:lExit

Depois da chamada da Thread AbortRun( .T. )

O loop da Thread continuou rodando, só funciona com oClasse:lExit
â–º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 de usuário

asimoes
Colaborador

Colaborador
 
Mensagens: 4919
Data de registro: 26 Abr 2007 16:48
Cidade/Estado: RIO DE JANEIRO-RJ
Curtiu: 341 vezes
Mens.Curtidas: 258 vezes

Duvida sobre Thread (Hb_ThreadStart)

Mensagempor asimoes » 24 Fev 2021 13:37

Completando:

Assim funciona, usando a função AbortRun() não

  oClasse:lExit := .F.

   fErase( "TIME.TXT" )
   
         nThread := Hb_ThreadStart( HB_BITOR( HB_THREAD_INHERIT_PUBLIC, ;
                                              HB_THREAD_INHERIT_PRIVATE, ;
                                              HB_THREAD_INHERIT_MEMVARS, ;
                                              HB_THREAD_MEMVARS_COPY ), ;
                                              { || Teste() } )
                                       
   altd()
   
   oClasse:lExit := .T.


13:35:06
13:35:11
13:35:16
FIM

O FIM siginifica que saiu do while
â–º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 de usuário

asimoes
Colaborador

Colaborador
 
Mensagens: 4919
Data de registro: 26 Abr 2007 16:48
Cidade/Estado: RIO DE JANEIRO-RJ
Curtiu: 341 vezes
Mens.Curtidas: 258 vezes

Duvida sobre Thread (Hb_ThreadStart)

Mensagempor Claudio Soto » 24 Fev 2021 15:59

Alexandre probá sin el parámetro HB_THREAD_MEMVARS_COPY

Porque si mal no recuerdo HB_THREAD_MEMVARS_COPY envía una copia de la variable (paso por valor) y no la variable en sí (paso por referencia)
Saludos.
Dr. Claudio Soto
(Uruguay)
http://srvet.blogspot.com
Avatar de usuário

Claudio Soto
Colaborador

Colaborador
 
Mensagens: 555
Data de registro: 27 Ago 2012 12:31
Cidade/Estado: Uruguay
Curtiu: 35 vezes
Mens.Curtidas: 166 vezes

Próximo



Retornar para Harbour

Quem está online

Usuários vendo este fórum: Nenhum usuário registrado online e 9 visitantes


Ola Amigo, espero que meu site e forum tem lhe beneficiado, com exemplos e dicas de programacao.
Entao divulgue o link da Doacao abaixo para seus amigos e redes sociais ou faça uma doacao para o site forum...
MUITO OBRIGADO PELA SUA DOACAO!
Faça uma doação para o forum
cron
v
Olá visitante, seja bem-vindo ao Fórum Clipper On Line!
Efetue o seu login ou faça o seu Registro