Usando multithread

Aqui você poderá oferecer suas Contribuições, Dicas e Tutoriais (Texto ou Vídeo) que sejam de interesse de todos.

Moderador: Moderadores

Avatar do usuário
JoséQuintas
Administrador
Administrador
Mensagens: 20267
Registrado em: 26 Fev 2007 11:59
Localização: São Paulo-SP

Usando multithread

Mensagem por JoséQuintas »

Usar multithread é simples, ao mesmo tempo que pode se tornar complexo.

Multithread é igual EXE separado, mas a thread principal é quem manda.
Fechou a thread principal fecha tudo ou, no mínimo, acaba com muitas variáveis.

Supondo que seu aplicativo tem a procedure Main, que é o início do aplicativo.
Altere o nome pra Main2, e crie outra Main.

Código: Selecionar todos

PROCEDURE Main

   hb_ThreadStart( { || Main2() } )
   hb_ThreadWaitForAll()

   RETURN

PROCEDURE HB_GTSYS

   REQUEST HB_GT_WVG_DEFAULT

   RETURN
Esta vai ser uma Main() invisível, esperando tudo acabar.
Seu aplicativo vai rodar na segunda thread.
Fechou o aplicativo, esta thread também fecha.

Seu aplicativo, se usar GTWVG, vai abrir uma outra janela GTWVG pra trabalhar.
Se for fivewin vai abrir dialog fivewin, se for hwgui vai abrir dialog hwgui, se for minigui vai dar erro porque minigui não está preparada pra isso.
Ou... vai abrir o que você quiser, você decide.
nota: minigui tem jeito de funcionar.
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/
Avatar do usuário
JoséQuintas
Administrador
Administrador
Mensagens: 20267
Registrado em: 26 Fev 2007 11:59
Localização: São Paulo-SP

Usando multithread

Mensagem por JoséQuintas »

O que uso aqui é hb_gtReload( "WVG" )

Isso cria um segundo ambiente de trabalho, com tela e teclado.
Mas a tela não aparece automático, só vai aparecer se você usar @ SAY, CLS, Inkey()

Código: Selecionar todos

PROCEDURE Modulo

   hb_gtReload( "WVG" )
   SetMode(33,100)
   CLS
   ? "Tecle algo"
   Inkey()

   RETURN
Está aí um módulo multithread.
A única diferença é o hb_gtReload("WVG") que vai carregar uma tela nova.
Se preferir: UMA DIALOG NOMODAL, uma dialog que não vai bloquear a anterior.

Basicamente é isso.
Temos uma rotina Main() invisível, e temos o módulo com sua própria janela.
Fechou o módulo, a Main() fecha.
Pode chamar o módulo quantas vezes quiser, vai abrir tantas janelas quanto chamar.

Aqui uso módulos GTWVG, HWGUI ou FIVEWIN.

O que tem de extraordinário nisso ? nada.
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/
Avatar do usuário
JoséQuintas
Administrador
Administrador
Mensagens: 20267
Registrado em: 26 Fev 2007 11:59
Localização: São Paulo-SP

Usando multithread

Mensagem por JoséQuintas »

Variáveis e arquivos

É aqui que a coisa fica interessante, pode facilitar ou complicar.

Arquivos são independentes por thread.
Pode usar isto em cada thread, uma não mexe com a outra

Código: Selecionar todos

USE clientes
...
CLOSE DATABASES
Variáveis PUBLIC e PRIVATE não são visíveis entre threads - este é o default, é o que eu uso, prefiro assim.

Mas quero controlar usuário que entrou no aplicativo, ou empresa em uso.

Aqui crio uma função pra cada, no lugar da variável pública.

Código: Selecionar todos

STATIC AppUserName( x )
   STATIC cAppUserName := ""
   IF x != Nil
      cAppUserName := x
   ENDIF
   RETURN cAppUserName
Nos módulos basta eu usar AppUserName()
E pra setar o inicial AppUserName( nomeusuario )

Resolvido o problema de variável pública.

Poderia ser array, poderia ser classe, poderia ser hash....
Sim poderia, mas desse jeito o compilador dá erro se colocar nome errado.

Pronto, resolvida a questão de variáveis que precisam ser visíveis.

Tem também a variável THREAD STATIC
É o mesmo que a STATIC mas cada thread tem a sua.

Por exemplo, num uso relativamente comum, criar um array com save screen.
Vai salvando na ida, e restaurando na volta.

Em multithread, cada thread tem sua sequência de save/restore screen, uma não pode interferir na outra.
Lembram: multithread é igual EXE separado. Vai salvar tela num EXE e restaurar no outro ? não dá certo.
Declarando esse array como THREAD STATIC , cada EXE/thread vai conter sua lista de save/restore screen, um EXE/thread não mexe com o outro.

Pronto, resolvida a questão de cada thread ter suas próprias variáveis especiais.

No resto, tanto faz, vai poder usar variável PUBLIC, PRIVATE, LOCAL, do jeito de sempre.
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/
Avatar do usuário
JoséQuintas
Administrador
Administrador
Mensagens: 20267
Registrado em: 26 Fev 2007 11:59
Localização: São Paulo-SP

Usando multithread

Mensagem por JoséQuintas »

De um modo geral é isso.

A questão de variáveis é importante.
É isso que pode impedir de usar LIB gráfica, não enxergar variáveis.

minigui costuma usar a variável pública _HMG_SYSDATA
Como é variável pública, não vai estar visível em outras threads.
Vai ser normal dar erro de não encontrar essa variável, se não for thread principal.
Isso tem solução ? sim. Pra cada situação, uma solução.
Resolver um problema não significa que resolveu todos.

Como a rotina de erros da minigui depende dessa variável, ao rodar em multithread você fica até sem mensagem de erro,
São situações a contornar.

É problema de multithread ? não
É problema da minigui ? não exatamente, ninguém usa em multithread, vai dizer que o que ninguém usa dá erro ? Se começarem a usar, aí ajustam a rotina de erro.

Tem também lib com INIT PROCEDURE e INIT FUNCTION.
Isso é executado ao carregar o aplicativo, mas somente uma vez, somente na thread principal.
Pode fazer falta pras outras threads.

Então, multithread é relativamente simples.
Mas nem toda lib é preparada pra isso.
O programador vai ter que entender isso, e fazer o que der.

Misturar LIBs é fácil ?
Teoricamente sim.
Na prática depende de não ter função repetida, com mesmo nome, mas fazendo coisa diferente.
Isso até sem multithread é problema.
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/
Avatar do usuário
JoséQuintas
Administrador
Administrador
Mensagens: 20267
Registrado em: 26 Fev 2007 11:59
Localização: São Paulo-SP

Usando multithread

Mensagem por JoséQuintas »

Problema conhecido em HWGUI.

HWGUI tem DIALOG e WINDOW.
Fazem praticamente a mesma coisa.
Mas WINDOW dá erro em multithread, esquisito.
Só não usar.
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/
Avatar do usuário
JoséQuintas
Administrador
Administrador
Mensagens: 20267
Registrado em: 26 Fev 2007 11:59
Localização: São Paulo-SP

Usando multithread

Mensagem por JoséQuintas »

Problema conhecido em FIVEWIN.

FIVEWIN mexe com a janela em uso.
Muda palette de cores, linhas/colunas, etc.
Só colocar hb_gtReload("WVG"), e dar uma janela invisível pro fivewin fazer suas mudanças.
Isso se houver janela GTWVG em uso antes da chamada do fivewin.
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/
Avatar do usuário
JoséQuintas
Administrador
Administrador
Mensagens: 20267
Registrado em: 26 Fev 2007 11:59
Localização: São Paulo-SP

Usando multithread

Mensagem por JoséQuintas »

Em GUI, quando dá erro, GUI fecha tudo que está em aberto.
Em multithread pode não fechar.
Vai ser normal ver janela ZUMBI.

Uma coisa é programa ZUMBI: não tem tela, tem que fechar no gerenciador de tarefas

Outra coisa é janela ZUMBI: a janela não foi destruída mas ficou sem programa, também tem que fechar no gerenciador de tarefas.
Aqui alterei a errorsys com uma chamada a uma função do fivewin: PostQuitMessage(0).
Isso fecha a thread, e destrói tudo que ela criou, não existe mais janela ZUMBI.

Essas coisas é o tempo que vai mostrar, conforme o que for acontecendo.

As janelas são criadas NO WINDOWS.
Elas não ficam presas ao programa, pelo contrário, é parte do programa que pode ficar preso à janela.
Mas se não tem mais a rotina de fechar janela porque o programa encerrou, clicar no fechar não vai fechar.
É onde entra encerrar a thread, ou fechar no gerenciador de tarefas.
Uma vez corrigido o erro, funciona normal.

Isto é só pra se preparar para o que pode acontecer.
Muitos já viram isso acontecer, e consideram normal.
Em multithread vai ser mais normal ainda.
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/
Avatar do usuário
JoséQuintas
Administrador
Administrador
Mensagens: 20267
Registrado em: 26 Fev 2007 11:59
Localização: São Paulo-SP

Usando multithread

Mensagem por JoséQuintas »

Uma situação de programa ZUMBI:

Imaginem um programa sem tela, e colocar lá Inkey(0)

Ok ?
É meio normal isso ?

Mas se não tem tela..... vai digitar ENTER aonde ?
O programa vai ficar eternamente esperando o ENTER.
Só mesmo fechando no gerenciador de tarefas.

Acho que esse seria um exemplo de um programa ZUMBI.
Ele tá lá rodando, e é obrigado a fechar no gerenciador de tarefas.

Durante o começo de uso pode ser normal fazer uma coisa dessas, ou em alguma situação eventual
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/
Avatar do usuário
JoséQuintas
Administrador
Administrador
Mensagens: 20267
Registrado em: 26 Fev 2007 11:59
Localização: São Paulo-SP

Usando multithread

Mensagem por JoséQuintas »

Compensa usar multithread ?

Sei lá... cada um que veja aonde pode usar.
Isso acontece com qualquer função do harbour, multithread não é diferente.
Você conhece a função, e quando tiver uma oportunidade faz uso dela ou não.
Multithread é a mesma coisa.

Em GUI já é normal ter várias janelas, pode colocar janelas pra fazer coisas diferentes.
Em GTWVG não é tão normal isso, começou por ser interessante ter várias janelas, continuou porque achei interessante ter arquivos independentes pra janelas independentes.
E agora continua interessante pra misturar LIBs.
Também achei interessante pra ter janelas com DBFs independentes, acabou com muito daquilo de ter que se preocupar com área aberta, índice aberto, filtro ativo, etc.

Cada um que veja se acha interessante usar multithread.

Talvez baste saber que existe, quando aparecer uma situação já sabe que pode usar.
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/
Responder