Rotina em Segundo Plano - Thread
Moderador: Moderadores
Rotina em Segundo Plano - Thread
Uma dúvida: thread só funciona na minigui? Eu uso modo console; é possível usar thread?
Editado pela última vez por Toledo em 28 Mar 2017 08:49, em um total de 1 vez.
Razão: O presente tópico foi dividido de um outro tópico da seção MiniGui, uma vez que seu conteúdo não tem relação com os objetivos daquela seção, onde só podem constar dúvidas técnicas de programação diretamente relacionadas com a MiniGui.
Razão: O presente tópico foi dividido de um outro tópico da seção MiniGui, uma vez que seu conteúdo não tem relação com os objetivos daquela seção, onde só podem constar dúvidas técnicas de programação diretamente relacionadas com a MiniGui.
Inacio de Carvalho Neto
Rotina em Segundo Plano
Sim é possível
Sun Tzu há mais de três mil anos cita nas epígrafes de seu livro “A Arte da Guerra“:
“Concentre-se nos pontos fortes, reconheça as fraquezas, agarre as oportunidades e proteja-se contra as ameaças”.
“Se não é vantajoso, nunca envie suas tropas; se não lhe rende ganhos, nunca utilize seus homens; se não é uma situação perigosa, nunca lute uma batalha precipitada”.
Até 2017 Desktop Console [ Legado ] Harbour | MinGW | DBF | CDX | FastReport | MySQL
Novos Projetos:
Desktop Visual Windev Desktop
Celular Android/iOS Windev Mobile
WEB Windev Web
Sejamos gratos a Deus.
“Concentre-se nos pontos fortes, reconheça as fraquezas, agarre as oportunidades e proteja-se contra as ameaças”.
“Se não é vantajoso, nunca envie suas tropas; se não lhe rende ganhos, nunca utilize seus homens; se não é uma situação perigosa, nunca lute uma batalha precipitada”.
Até 2017 Desktop Console [ Legado ] Harbour | MinGW | DBF | CDX | FastReport | MySQL
Novos Projetos:
Desktop Visual Windev Desktop
Celular Android/iOS Windev Mobile
WEB Windev Web
Sejamos gratos a Deus.
Rotina em Segundo Plano
Tem como vc me ensinar a fazer isso, ou me passar algum link onde ensina? Eu nunca usei e não faço ideia de como começar. Já li alguma coisa aqui, mas sempre voltado à Minigui.
Inacio de Carvalho Neto
Rotina em Segundo Plano
Sun Tzu há mais de três mil anos cita nas epígrafes de seu livro “A Arte da Guerra“:
“Concentre-se nos pontos fortes, reconheça as fraquezas, agarre as oportunidades e proteja-se contra as ameaças”.
“Se não é vantajoso, nunca envie suas tropas; se não lhe rende ganhos, nunca utilize seus homens; se não é uma situação perigosa, nunca lute uma batalha precipitada”.
Até 2017 Desktop Console [ Legado ] Harbour | MinGW | DBF | CDX | FastReport | MySQL
Novos Projetos:
Desktop Visual Windev Desktop
Celular Android/iOS Windev Mobile
WEB Windev Web
Sejamos gratos a Deus.
“Concentre-se nos pontos fortes, reconheça as fraquezas, agarre as oportunidades e proteja-se contra as ameaças”.
“Se não é vantajoso, nunca envie suas tropas; se não lhe rende ganhos, nunca utilize seus homens; se não é uma situação perigosa, nunca lute uma batalha precipitada”.
Até 2017 Desktop Console [ Legado ] Harbour | MinGW | DBF | CDX | FastReport | MySQL
Novos Projetos:
Desktop Visual Windev Desktop
Celular Android/iOS Windev Mobile
WEB Windev Web
Sejamos gratos a Deus.
Rotina em Segundo Plano
Testei e funcionou.
Mas, sinceramente, acho que ainda não entendi a ideia.
Pensei que a ideia da thread seria a rotina ficar rodando em segundo plano, sem aparecer na tela. Não é isso? Pelo menos não é isso que está acontecendo no caso aqui. Ele simplesmente desviou para a função que era pra ficar rodando em segundo plano, aparecendo normalmente na tela.
Em suma, não entendi qual a diferença para uma chamada normal da função, nem qual a vantagem dessa aplicação.
Poderia me explicar, por favor?
Mas, sinceramente, acho que ainda não entendi a ideia.
Pensei que a ideia da thread seria a rotina ficar rodando em segundo plano, sem aparecer na tela. Não é isso? Pelo menos não é isso que está acontecendo no caso aqui. Ele simplesmente desviou para a função que era pra ficar rodando em segundo plano, aparecendo normalmente na tela.
Em suma, não entendi qual a diferença para uma chamada normal da função, nem qual a vantagem dessa aplicação.
Poderia me explicar, por favor?
Inacio de Carvalho Neto
-
Claudio Soto
- Colaborador

- Mensagens: 566
- Registrado em: 27 Ago 2012 12:31
- Localização: Uruguay
- Contato:
Rotina em Segundo Plano
Este talvez sea un ejemplo más claro:
Código: Selecionar todos
// Multi-Thread Demo WITH INHERIT PUBLIC vars, contrib by Roberto Lopez, March 2017
// NOTE: This is a classic ( conventional ) way how to use Multi-Thread at level of the OS, share ( inherit ) public and static vars
#include <hmg.ch>
#include "hbthread.ch"
FUNCTION Main
aThread := { NIL, NIL }
IF !hb_mtvm()
MSGSTOP("There is no support for multi-threading")
QUIT
ENDIF
DEFINE WINDOW Form_1 AT 301 , 503 WIDTH 550 HEIGHT 350 MAIN
DEFINE BUTTON Button_1
ROW 10
COL 10
WIDTH 160
HEIGHT 28
ACTION ( aThread[ 1 ] := hb_threadStart( HB_THREAD_INHERIT_PUBLIC , @Show_Time() ) )
CAPTION "Start Clock Thread"
END BUTTON
DEFINE BUTTON Button_2
ROW 50
COL 10
WIDTH 160
HEIGHT 28
ACTION ( aThread[ 2 ] := hb_threadStart( HB_THREAD_INHERIT_PUBLIC , @Show_Progress() ) )
CAPTION "Start ProgressBar Thread"
END BUTTON
DEFINE LABEL Label_1
ROW 10
COL 360
WIDTH 120
HEIGHT 24
VALUE "Clock Here!"
END LABEL
DEFINE PROGRESSBAR ProgressBar_1
ROW 250
COL 360
WIDTH 150
HEIGHT 30
RANGEMIN 1
RANGEMAX 10
VALUE 0
END PROGRESSBAR
DEFINE BUTTON Button_3
ROW 170
COL 140
WIDTH 260
HEIGHT 28
ACTION button_3_action()
CAPTION "UI Still Responding to User Events!!!"
END BUTTON
DEFINE BUTTON Button_4
ROW 250
COL 10
WIDTH 160
HEIGHT 28
ACTION button_4_action()
CAPTION "Terminate all Threads"
END BUTTON
END WINDOW
Form_1.Center
Form_1.Activate
Return
FUNCTION Show_Time()
Form_1.button_1.enabled := .F. // disable 'Start Thread' button to avoid accidentally start a new thread!
DO WHILE .T. // thread infinite loop
Form_1.label_1.value := Time()
hb_idleSleep( .5 )
ENDDO
RETURN nil
FUNCTION Show_Progress()
Form_1.button_2.enabled := .F. // disable 'Start Progress' button to avoid accidentally start a new thread!
DO WHILE .T. // thread infinite loop
nValue := Form_1.progressBar_1.value
nValue ++
if nValue > 10
nValue := 1
endif
Form_1.progressBar_1.value := nValue
hb_idleSleep( .5 )
ENDDO
RETURN nil
FUNCTION button_3_action
MSGINFO('Clock and ProgressBar keep updating even the main thread is stopped at this MsgInfo!!!')
Return Nil
FUNCTION button_4_action
LOCAL i
FOR i := 1 TO HMG_LEN( aThread )
IF aThread[ i ] <> NIL
hb_threadDetach( aThread[ i ] ) // close thread handle
hb_threadQuitRequest( aThread[ i ] ) // terminate thread
aThread[ i ] := NIL
ENDIF
NEXT
Form_1.progressBar_1.value := 0
Form_1.label_1.value := "Clock Here!"
Form_1.button_1.enabled := .T.
Form_1.button_2.enabled := .T.
Return Nil
- JoséQuintas
- Administrador

- Mensagens: 20267
- Registrado em: 26 Fev 2007 11:59
- Localização: São Paulo-SP
Rotina em Segundo Plano
Talvez com GTWVG fique mais claro isso.
Pode ou não ter tela.
Na prática vão ter TRES rotinas.
A principal, invisível, e mais duas com tela, totalmente independentes.
IMPORTANTÍSSIMO:
Na thread pode ser necessário configurar SET DATE, RddSetDefault(), etc.
É realmente como se fosse um programa em separado.
Mas se a Main() encerrar, todas as threads se encerram, por isso o uso de hb_ThreadWaitForAll().
E por último:
A janela GTWVG pode ser útil mesmo com outras GUIs, podendo ser usada invisível.
Não sei se isso permitiria usar o debug normal do Harbour em ambiente GUI...
Mas se misturar multithread nisso... talvez desse.... rs
Pode ou não ter tela.
Código: Selecionar todos
PROCEDURE Main
hb_ThreadStart( { || Teste() } )
hb_ThreadStart( { || Teste() } )
hb_ThreadWaitForAll()
RETURN
FUNCTION Teste()
hb_gtReload( "WVG" )
cVar := Space(10)
SetMode( 25, 80 )
CLS
@ 2, 20 SAY "teste" GET cVar
READ
RETURN NIL
A principal, invisível, e mais duas com tela, totalmente independentes.
IMPORTANTÍSSIMO:
Na thread pode ser necessário configurar SET DATE, RddSetDefault(), etc.
É realmente como se fosse um programa em separado.
Mas se a Main() encerrar, todas as threads se encerram, por isso o uso de hb_ThreadWaitForAll().
E por último:
A janela GTWVG pode ser útil mesmo com outras GUIs, podendo ser usada invisível.
Não sei se isso permitiria usar o debug normal do Harbour em ambiente GUI...
Mas se misturar multithread nisso... talvez desse.... rs
José M. C. Quintas
Harbour 3.2, mingw, gtwvg mt, fivewin 25.04, multithread, dbfcdx, MySQL, ADOClass, PDFClass, SefazClass, (hwgui mt), (hmg3), (hmg extended), (oohg), PNotepad, ASP, stored procedure, stored function, Linux (Flagship/harbour 3.2)
"The world is full of kings and queens, who blind our eyes and steal our dreams Its Heaven and Hell"
https://github.com/JoseQuintas/
Harbour 3.2, mingw, gtwvg mt, fivewin 25.04, multithread, dbfcdx, MySQL, ADOClass, PDFClass, SefazClass, (hwgui mt), (hmg3), (hmg extended), (oohg), PNotepad, ASP, stored procedure, stored function, Linux (Flagship/harbour 3.2)
"The world is full of kings and queens, who blind our eyes and steal our dreams Its Heaven and Hell"
https://github.com/JoseQuintas/
Rotina em Segundo Plano
Quintas, teu exemplo não funcionou aqui. Ele compila e teoricamente roda, mas não acontece nada; não aparece tela alguma, e aparentemente nem executa a function teste().
Claudio, ainda vou testar o teu exemplo.
Claudio, ainda vou testar o teu exemplo.
Inacio de Carvalho Neto
- JoséQuintas
- Administrador

- Mensagens: 20267
- Registrado em: 26 Fev 2007 11:59
- Localização: São Paulo-SP
Rotina em Segundo Plano
Importante também na compilação:
HBMK2 test -mt gtwvg.hbc
o -mt indica multithread.
HBMK2 test -mt gtwvg.hbc
o -mt indica multithread.
José M. C. Quintas
Harbour 3.2, mingw, gtwvg mt, fivewin 25.04, multithread, dbfcdx, MySQL, ADOClass, PDFClass, SefazClass, (hwgui mt), (hmg3), (hmg extended), (oohg), PNotepad, ASP, stored procedure, stored function, Linux (Flagship/harbour 3.2)
"The world is full of kings and queens, who blind our eyes and steal our dreams Its Heaven and Hell"
https://github.com/JoseQuintas/
Harbour 3.2, mingw, gtwvg mt, fivewin 25.04, multithread, dbfcdx, MySQL, ADOClass, PDFClass, SefazClass, (hwgui mt), (hmg3), (hmg extended), (oohg), PNotepad, ASP, stored procedure, stored function, Linux (Flagship/harbour 3.2)
"The world is full of kings and queens, who blind our eyes and steal our dreams Its Heaven and Hell"
https://github.com/JoseQuintas/
Rotina em Segundo Plano
Ah, sim, agora funcionou.
Mas, ao colocar na minha aplicação, está dando erro de variável us inexistente, embora a variável us esteja predefinida como public.
Como faço para a thread ficar invisível?
Outra coisa: em testes feitos num passado já distante de tela oculta (não era com thread, e acho que era no xharbour), quando dava erro na tela oculta, a tela principal travava. Isso ocorre também com thread?
Mas, ao colocar na minha aplicação, está dando erro de variável us inexistente, embora a variável us esteja predefinida como public.
Como faço para a thread ficar invisível?
Outra coisa: em testes feitos num passado já distante de tela oculta (não era com thread, e acho que era no xharbour), quando dava erro na tela oculta, a tela principal travava. Isso ocorre também com thread?
Inacio de Carvalho Neto
Rotina em Segundo Plano
Mais uma coisa, por favor: usando a gtwvg, mesmo sem usar a thread, minha tela ficou cortada. Veja o anexo.
Além disso, quando abro o programa, mesmo a tela principal abre numa segunda tela, ficando a primeira tela toda preta. Por que isso?
Além disso, quando abro o programa, mesmo a tela principal abre numa segunda tela, ficando a primeira tela toda preta. Por que isso?
Inacio de Carvalho Neto
- JoséQuintas
- Administrador

- Mensagens: 20267
- Registrado em: 26 Fev 2007 11:59
- Localização: São Paulo-SP
Rotina em Segundo Plano
Pra deixar GTWVG como default:
Provavelmente tem mais a GT console por detrás.
E não precisa hb_gtReload("WVG"), isso é só pra thread adicional ter janela adicional
Em multithread, o default é que variáveis não são passadas pras threads, nem mesmo as públicas.
Caso precise disso, a opção é usar parâmetros.
Por exemplo:
Código: Selecionar todos
PROCEDURE hb_GTSYS()
REQUEST HB_GT_WVG_DEFAULT
RETURN
E não precisa hb_gtReload("WVG"), isso é só pra thread adicional ter janela adicional
Em multithread, o default é que variáveis não são passadas pras threads, nem mesmo as públicas.
Caso precise disso, a opção é usar parâmetros.
Por exemplo:
Código: Selecionar todos
// Inherit copy of public
// hb_threadJoin( hb_threadStart( HB_BITOR( HB_THREAD_INHERIT_PUBLIC, HB_THREAD_MEMVARS_COPY ), @thFunc() ) )
// ? "Inherit copy of privates."
// hb_threadJoin( hb_threadStart( HB_BITOR( HB_THREAD_INHERIT_PRIVATE, HB_THREAD_MEMVARS_COPY ), @thFunc() ) )
// ? "Inherit copy of publics and privates."
// hb_threadJoin( hb_threadStart( HB_BITOR( HB_THREAD_INHERIT_MEMVARS, HB_THREAD_MEMVARS_COPY ), @thFunc() ) )
José M. C. Quintas
Harbour 3.2, mingw, gtwvg mt, fivewin 25.04, multithread, dbfcdx, MySQL, ADOClass, PDFClass, SefazClass, (hwgui mt), (hmg3), (hmg extended), (oohg), PNotepad, ASP, stored procedure, stored function, Linux (Flagship/harbour 3.2)
"The world is full of kings and queens, who blind our eyes and steal our dreams Its Heaven and Hell"
https://github.com/JoseQuintas/
Harbour 3.2, mingw, gtwvg mt, fivewin 25.04, multithread, dbfcdx, MySQL, ADOClass, PDFClass, SefazClass, (hwgui mt), (hmg3), (hmg extended), (oohg), PNotepad, ASP, stored procedure, stored function, Linux (Flagship/harbour 3.2)
"The world is full of kings and queens, who blind our eyes and steal our dreams Its Heaven and Hell"
https://github.com/JoseQuintas/
Rotina em Segundo Plano
Não deu certo.
Fiz assim:
Travou tudo no início.
Fiz assim:
Código: Selecionar todos
function main
hb_ThreadStart( { || Teste("I","Inacio","25/03/17","comin") } )
hb_ThreadWaitForAll()
REQUEST HB_GT_WVG_DEFAULT
...
return
FUNCTION Teste()
parameters us, nmus, vers, seis
cVar := Space(10)
cadativ("Teste","Teste: início"," ",0,us,0,0," ")
SetMode( 25, 80 )
CLS
@ 2, 20 SAY "teste" GET cVar
READ
RETURN NIL
Inacio de Carvalho Neto
- JoséQuintas
- Administrador

- Mensagens: 20267
- Registrado em: 26 Fev 2007 11:59
- Localização: São Paulo-SP
Rotina em Segundo Plano
Confundiu tudo.
Código: Selecionar todos
PROCEDURE Main
hb_ThreadStart( { || Teste() } )
hb_ThreadStart( { || Teste() } )
hb_ThreadWaitForAll()
RETURN
FUNCTION Teste()
hb_gtReload( "WVG" )
cVar := Space(10)
SetMode( 25, 80 )
CLS
@ 2, 20 SAY "teste" GET cVar
READ
RETURN NIL
PROCEDURE hb_GTSYS()
REQUEST HB_GT_WVG_DEFAULT
RETURN
José M. C. Quintas
Harbour 3.2, mingw, gtwvg mt, fivewin 25.04, multithread, dbfcdx, MySQL, ADOClass, PDFClass, SefazClass, (hwgui mt), (hmg3), (hmg extended), (oohg), PNotepad, ASP, stored procedure, stored function, Linux (Flagship/harbour 3.2)
"The world is full of kings and queens, who blind our eyes and steal our dreams Its Heaven and Hell"
https://github.com/JoseQuintas/
Harbour 3.2, mingw, gtwvg mt, fivewin 25.04, multithread, dbfcdx, MySQL, ADOClass, PDFClass, SefazClass, (hwgui mt), (hmg3), (hmg extended), (oohg), PNotepad, ASP, stored procedure, stored function, Linux (Flagship/harbour 3.2)
"The world is full of kings and queens, who blind our eyes and steal our dreams Its Heaven and Hell"
https://github.com/JoseQuintas/
- JoséQuintas
- Administrador

- Mensagens: 20267
- Registrado em: 26 Fev 2007 11:59
- Localização: São Paulo-SP
Rotina em Segundo Plano
Ou vamos em partes:
definir GTWVG como default, exatamente deste jeito, sem mudanças.
uma sub-rotina pra ter tela isolada da principal
E rotina principal, sem tela, aguardando as threads encerrarem
definir GTWVG como default, exatamente deste jeito, sem mudanças.
Código: Selecionar todos
PROCEDURE hb_GTSYS()
REQUEST HB_GT_WVG_DEFAULT
RETURN
Código: Selecionar todos
FUNCTION Teste()
hb_gtReload( "WVG" ) // isto gera tela isolada, com tela/teclado próprio
cVar := Space(10)
SetMode( 25, 80 )
CLS
@ 2, 20 SAY "teste" GET cVar
READ
RETURN NIL
Código: Selecionar todos
PROCEDURE Main
hb_ThreadStart( { || Teste() } )
hb_ThreadStart( HB_THREAD_INHERIT_PUBLIC, HB_THREAD_MEMVARS_COPY, { || Teste() } ) // variáveis públicas visíveis na thread
hb_ThreadWaitForAll()
RETURN
José M. C. Quintas
Harbour 3.2, mingw, gtwvg mt, fivewin 25.04, multithread, dbfcdx, MySQL, ADOClass, PDFClass, SefazClass, (hwgui mt), (hmg3), (hmg extended), (oohg), PNotepad, ASP, stored procedure, stored function, Linux (Flagship/harbour 3.2)
"The world is full of kings and queens, who blind our eyes and steal our dreams Its Heaven and Hell"
https://github.com/JoseQuintas/
Harbour 3.2, mingw, gtwvg mt, fivewin 25.04, multithread, dbfcdx, MySQL, ADOClass, PDFClass, SefazClass, (hwgui mt), (hmg3), (hmg extended), (oohg), PNotepad, ASP, stored procedure, stored function, Linux (Flagship/harbour 3.2)
"The world is full of kings and queens, who blind our eyes and steal our dreams Its Heaven and Hell"
https://github.com/JoseQuintas/
