Multi thread, XHarbour 1.0.0 Console
Moderador: Moderadores
Multi thread, XHarbour 1.0.0 Console
Srs.,
Decidi usar a função startthread() para, em determinados casos, fazer meu programa enviar do cliente para mim, em background, um email com algumas informações que me interessam, usando uma função de envio/recebimento de emails do padrinho Leonardo Sygecom. E isso funciona 100%.
O usuário nem percebe que o programa está trabalhando simultaneamente (na surdina) em outra coisa... Chic.
Pra isso, basta eu indicar, no HBMAKE, que vou "usar biblioteca multi thread".
Agora, a encrenca: entre as tais informações que me interessam, estão incluidos alguns arquivos, os quais eu desejo zipar usando a hb_zipfile() e anexar ao email... Em outras palavras, quero usar o THREAD junto com o ZIPFILE.
(ah, deixando o THREAD de lado: a função de envio de emails aceita normalmente mandar arquivos em anexo. Funciona perfeito.)
O que acontece:
a) se eu rodo o HBMAKE SEM a opção "usar a biblioteca multi thread" e aponto para a HBZIP.LIB, compila normal e roda normal, a ZIPagem é feita sem erro. Mas a THREAD não funciona, óbvio.
b) se eu faço a mesma coisa e MARCO a opção "usar a multi thread" (para que a função startthread() rode), nem compila, dá o seguinte erro: "Error: Unresolved external '_errno' reference from c:\xharbour\lib\hbzip.lib|zipfile'.
Aí, imaginando que a ZIP.LIB não funcione em MT, tentamos (eu e o Leo) usar uma DLL...
c) agora, com a opção "usar a multi thread" marcada e apontando para a nova HBZIPDLL.LIB, compila normal mas, quando rodo o EXE, ele ABORTA, exatamente quando chama a função da ZIPagem... Operação ilegal...
Bão, sou novato em XHarbour, nem sei se consegui explicar direito a encrenca. Alguém aí dá uma luz?
Ah:
a) tentei em vários PCs, com XP, 98 e ME. Mesmo resultado em todos...
b) tentei usar a backgroundrun(), mas não acertei... O segundo processamento não ocorre efetivamente em background! Só volta ao primeiro depois que o segundo termina. Talvez eu tenha feito algo errado.
c) um tár de MUTEX tem algo a ver com essa encrenca?
Decidi usar a função startthread() para, em determinados casos, fazer meu programa enviar do cliente para mim, em background, um email com algumas informações que me interessam, usando uma função de envio/recebimento de emails do padrinho Leonardo Sygecom. E isso funciona 100%.
O usuário nem percebe que o programa está trabalhando simultaneamente (na surdina) em outra coisa... Chic.
Pra isso, basta eu indicar, no HBMAKE, que vou "usar biblioteca multi thread".
Agora, a encrenca: entre as tais informações que me interessam, estão incluidos alguns arquivos, os quais eu desejo zipar usando a hb_zipfile() e anexar ao email... Em outras palavras, quero usar o THREAD junto com o ZIPFILE.
(ah, deixando o THREAD de lado: a função de envio de emails aceita normalmente mandar arquivos em anexo. Funciona perfeito.)
O que acontece:
a) se eu rodo o HBMAKE SEM a opção "usar a biblioteca multi thread" e aponto para a HBZIP.LIB, compila normal e roda normal, a ZIPagem é feita sem erro. Mas a THREAD não funciona, óbvio.
b) se eu faço a mesma coisa e MARCO a opção "usar a multi thread" (para que a função startthread() rode), nem compila, dá o seguinte erro: "Error: Unresolved external '_errno' reference from c:\xharbour\lib\hbzip.lib|zipfile'.
Aí, imaginando que a ZIP.LIB não funcione em MT, tentamos (eu e o Leo) usar uma DLL...
c) agora, com a opção "usar a multi thread" marcada e apontando para a nova HBZIPDLL.LIB, compila normal mas, quando rodo o EXE, ele ABORTA, exatamente quando chama a função da ZIPagem... Operação ilegal...
Bão, sou novato em XHarbour, nem sei se consegui explicar direito a encrenca. Alguém aí dá uma luz?
Ah:
a) tentei em vários PCs, com XP, 98 e ME. Mesmo resultado em todos...
b) tentei usar a backgroundrun(), mas não acertei... O segundo processamento não ocorre efetivamente em background! Só volta ao primeiro depois que o segundo termina. Talvez eu tenha feito algo errado.
c) um tár de MUTEX tem algo a ver com essa encrenca?
MUTEX é, a grosso modo, um instrumento de controle de semáforos para aplicação em threads, ou mesmo de aplicações. Ou seja, pode ter utilidade (não relacionado ao erro em si), dependendo de como foi criada a lógica para ZIPar e enviar o eMail. Se há, por exemplo, uma thread para criar o ZIP e outra para enviar o eMail, é claro que um semáforo será necessário.
Agora, quanto ao erro em si, esse tal "Error: Unresolved external" é típico de símbolo não referenciado no script de linkedição. Isso é universal, independente de linguagem. Parece estar faltando biblioteca aí.
Agora, quanto ao erro em si, esse tal "Error: Unresolved external" é típico de símbolo não referenciado no script de linkedição. Isso é universal, independente de linguagem. Parece estar faltando biblioteca aí.
[]'s
Maligno
---
Não respondo questões técnicas através de MP ou eMail. Não insista.
As dúvidas devem ser postadas no fórum. Desta forma, todos poderão
se beneficiar das respostas.
---
Se um dia precisar de uma transfusão de sangue você perceberá como
é importante a figura do doador. Procure o hemocentro de sua cidade e
se informe sobre a doação de sangue, plaquetas e medula óssea. Doe!
Maligno
---
Não respondo questões técnicas através de MP ou eMail. Não insista.
As dúvidas devem ser postadas no fórum. Desta forma, todos poderão
se beneficiar das respostas.
---
Se um dia precisar de uma transfusão de sangue você perceberá como
é importante a figura do doador. Procure o hemocentro de sua cidade e
se informe sobre a doação de sangue, plaquetas e medula óssea. Doe!
Como eu disse, é um thread só. Depois do ZIP pronto, eu tento mandar o email em background, via thread.Se há, por exemplo, uma thread para criar o ZIP e outra para enviar o eMail, é claro que um semáforo será necessário.
Repetindo, com outras palavras: o ZIP e o EMAIL/Thread funcinam 100%, quando isolados. Misturou, dá pau.
Releia o meu post.Agora, quanto ao erro em si, esse tal "Error: Unresolved external" é típico de símbolo não referenciado no script de linkedição. Isso é universal, independente de linguagem. Parece estar faltando biblioteca aí.
Os itens A, B e C estão numa seqüência... Do item A pro B, a mesma LIB (que funciona no A) continua lá, mas não compila nem linka porque eu marquei o "usar biblioteca multi thread". Do item B pro C, mudei de LIB, compila normal (não há NADA unresolved), compila, linka, mas dá erro de runtime.
Então, não é FALTA de LIB. Talvez seja FALTA de LIBs compatíveis... Talvez alguém saiba dizer se é porque a LIB pra modo "não-MultiTarefa" não funciona em modo "MT"...
Então, recapitulando...
Se separados tudo funciona bem, mas juntos não, posso deduzir que a biblioteca relacionada à MT pode conter um objeto de mesmo nome, integrante de HBZIP. Se a biblioteca de MT, no script de linkedição, é relacionada ANTES da HBZIP, será este objeto (sem o símbolo _errno) o linkado. Daí o erro. Uma tentativa de mudar isso, sem garantia de sucesso, seria trocar essas LIBs de lugar.b) se eu faço a mesma coisa e MARCO a opção "usar a multi thread" (para que a função startthread() rode), nem compila, dá o seguinte erro: "Error: Unresolved external '_errno' reference from c:\xharbour\lib\hbzip.lib|zipfile'.
Qual a mensagem de erro? Você só falou de "operação ilegal".Aí, imaginando que a ZIP.LIB não funcione em MT, tentamos (eu e o Leo) usar uma DLL...
c) agora, com a opção "usar a multi thread" marcada e apontando para a nova HBZIPDLL.LIB, compila normal mas, quando rodo o EXE, ele ABORTA, exatamente quando chama a função da ZIPagem... Operação ilegal...
[]'s
Maligno
---
Não respondo questões técnicas através de MP ou eMail. Não insista.
As dúvidas devem ser postadas no fórum. Desta forma, todos poderão
se beneficiar das respostas.
---
Se um dia precisar de uma transfusão de sangue você perceberá como
é importante a figura do doador. Procure o hemocentro de sua cidade e
se informe sobre a doação de sangue, plaquetas e medula óssea. Doe!
Maligno
---
Não respondo questões técnicas através de MP ou eMail. Não insista.
As dúvidas devem ser postadas no fórum. Desta forma, todos poderão
se beneficiar das respostas.
---
Se um dia precisar de uma transfusão de sangue você perceberá como
é importante a figura do doador. Procure o hemocentro de sua cidade e
se informe sobre a doação de sangue, plaquetas e medula óssea. Doe!
A tal operação "não legal"
é a seguinte:
Código: Selecionar todos
*** no Win98
CHEQUE3 causou uma falha de página inválida no
módulo HARBOUR.DLL em 0187:0063bbeb.
Registros:
EAX=00000001 CS=0187 EIP=0063bbeb EFLGS=00010202
EBX=00000400 SS=018f ESP=00a5f46c EBP=00a5f474
ECX=007eb53c DS=018f ESI=004b4fc4 FS=424f
EDX=00000000 ES=018f EDI=00000000 GS=0000
Bytes em CS:EIP:
8b 12 66 81 7a 0e ff 00 73 0b 8b 51 28 8b 12 0f
Esvaziamento da pilha:
004b4fc4 00505908 00a5f5d8 005a52e0 00000001 00000400 00434759 00a5f490 0055d938 3a48543a 52413a31 50495a51 00430000 00a5f4a8 00505758 3a48543aSe fosse Clipper/BLinker até dava pra ver o mapa. Mas no XHarbour acredito que este recurso não existe.
[]'s
Maligno
---
Não respondo questões técnicas através de MP ou eMail. Não insista.
As dúvidas devem ser postadas no fórum. Desta forma, todos poderão
se beneficiar das respostas.
---
Se um dia precisar de uma transfusão de sangue você perceberá como
é importante a figura do doador. Procure o hemocentro de sua cidade e
se informe sobre a doação de sangue, plaquetas e medula óssea. Doe!
Maligno
---
Não respondo questões técnicas através de MP ou eMail. Não insista.
As dúvidas devem ser postadas no fórum. Desta forma, todos poderão
se beneficiar das respostas.
---
Se um dia precisar de uma transfusão de sangue você perceberá como
é importante a figura do doador. Procure o hemocentro de sua cidade e
se informe sobre a doação de sangue, plaquetas e medula óssea. Doe!
- Luciano Bonfim
- Usuário Nível 3

- Mensagens: 414
- Registrado em: 23 Ago 2007 09:34
- Localização: Rio de Janeiro / São Paulo
- Contato:
Amigo
Já tentou mudar a ordem que essas libs aparecem no seu script, por exemplo quando comecei a usar a lib HWGUI penei pra descobrir que tenho que referenciá-la antes da What32 senäo näo rodava de jeito nenhum. bastou eu inverter a ordem que elas apareciam no script que funcionou
inverte pra ver se funciona
Boa Sorte
Já tentou mudar a ordem que essas libs aparecem no seu script, por exemplo quando comecei a usar a lib HWGUI penei pra descobrir que tenho que referenciá-la antes da What32 senäo näo rodava de jeito nenhum. bastou eu inverter a ordem que elas apareciam no script que funcionou
inverte pra ver se funciona
Boa Sorte
Muito Obrigado,
Luciano Bonfim de Azevedo
www.bonfim.com.br
luciano@bonfim.com.br
www.linkedin.com/in/lucianobonfim
Skype : lucianobonfim
Luciano Bonfim de Azevedo
www.bonfim.com.br
luciano@bonfim.com.br
www.linkedin.com/in/lucianobonfim
Skype : lucianobonfim
- Luciano Bonfim
- Usuário Nível 3

- Mensagens: 414
- Registrado em: 23 Ago 2007 09:34
- Localização: Rio de Janeiro / São Paulo
- Contato:
no meu caso esse "básico" que eu nao sabia me fez perder uns... 3 dias... rsrsrsrs
Muito Obrigado,
Luciano Bonfim de Azevedo
www.bonfim.com.br
luciano@bonfim.com.br
www.linkedin.com/in/lucianobonfim
Skype : lucianobonfim
Luciano Bonfim de Azevedo
www.bonfim.com.br
luciano@bonfim.com.br
www.linkedin.com/in/lucianobonfim
Skype : lucianobonfim
Bem, finalmente achei uma solução que talvez não seja a melhor tecnicamente, mas que funciona: a função HB_OpenProcess() - que é algo como o RUN...
O processo PARENT ("pai"), que é o EXE principal sendo rodado, chama um outro EXE como CHILD ("filho"), e é o EXE Filho que envia o email, em background, sem abrir uma segunda janela. Com isso, o envio do email pode demorar o tempo que for preciso: o EXE Pai continua a execução normal, como se não houvesse o EXE Filho rodando... Nem dá pra perceber.
E dá pra trocar informações entre os dois processos! Eu não precisei usar isto, pois neste meu caso específico eu consegui manter os dois processos independentes, mas é possível passar parâmetros do Pai pro Filho e ler retornos do Filho pro Pai...
Complementando: esta função pode ser muito útil, por exemplo, no caso de um relatório muito extenso: o usuário escolhe lá as opções e, ao invés de ficar esperando o EXE Pai processar o relatório, ele pode ir fazer outra coisa, já que o EXE Filho é quem vai ficar processamento o relatório, em background...
O processo PARENT ("pai"), que é o EXE principal sendo rodado, chama um outro EXE como CHILD ("filho"), e é o EXE Filho que envia o email, em background, sem abrir uma segunda janela. Com isso, o envio do email pode demorar o tempo que for preciso: o EXE Pai continua a execução normal, como se não houvesse o EXE Filho rodando... Nem dá pra perceber.
E dá pra trocar informações entre os dois processos! Eu não precisei usar isto, pois neste meu caso específico eu consegui manter os dois processos independentes, mas é possível passar parâmetros do Pai pro Filho e ler retornos do Filho pro Pai...
Complementando: esta função pode ser muito útil, por exemplo, no caso de um relatório muito extenso: o usuário escolhe lá as opções e, ao invés de ficar esperando o EXE Pai processar o relatório, ele pode ir fazer outra coisa, já que o EXE Filho é quem vai ficar processamento o relatório, em background...
- sygecom
- Administrador

- Mensagens: 7131
- Registrado em: 21 Jul 2006 10:12
- Localização: Alvorada-RS
- Contato:
Eolo, faça o seguinte teste ai ! eu fiz aqui e deu certo...
Não link em seu Script nem a HBZIP e nem a HBZIPDLL depois pegue a DLL que vc gerou da HBZIP(através do BAT "dll_b32.bat" da pasta CONTRIB\HBZIP) e coloque na pasta do seu sistema, e use conforme abaixo:
Abraços
Leonardo Machado
Não link em seu Script nem a HBZIP e nem a HBZIPDLL depois pegue a DLL que vc gerou da HBZIP(através do BAT "dll_b32.bat" da pasta CONTRIB\HBZIP) e coloque na pasta do seu sistema, e use conforme abaixo:
Código: Selecionar todos
Function Teste
hDll := LoadLibrary( "hbzipdll.dll" ) // carrega a DLL para usar
vNome_zip := "LEO.zip" // nome do arq. ZIP
aArq:={"AGENDA.DBF"} // arquivo a ser Zipado
HB_LibDo("hb_zipfile","vNome_zip,aARQ, 9, ,.t., "SENHA",.F.,.F.,") // campacta
LibFree( hDll ) // libera a DLL
StartThread( @Envia_Email(),vNome_zip)
....
....
....
ReturnLeonardo Machado
Leonardo Machado
xHarbour.org + Hwgui + PostgreSql
xHarbour.org + Hwgui + PostgreSql
Leonardo,
Vou anotar e examinar a sua sugestão mas, como falamos, não vai ajudar muito, pq no meu caso é preciso um EXE a mais e, no seu, uma DLL a mais. Então...
Bão, dei uma melhorada no meu EMAIL.exe e, agora, ele ficou "genérico" e mais fácil de usar: o EXE "parent" passa todas as informações pra ele (desde conta e senha até anexos, assunto etc e tals), via os argumentos da HB_OpenProcess(), e ele só bota o trem no correio, de acordo com as conformidades!
Vou anotar e examinar a sua sugestão mas, como falamos, não vai ajudar muito, pq no meu caso é preciso um EXE a mais e, no seu, uma DLL a mais. Então...
Bão, dei uma melhorada no meu EMAIL.exe e, agora, ele ficou "genérico" e mais fácil de usar: o EXE "parent" passa todas as informações pra ele (desde conta e senha até anexos, assunto etc e tals), via os argumentos da HB_OpenProcess(), e ele só bota o trem no correio, de acordo com as conformidades!
Grande Eolo,Eolo escreveu: Complementando: esta função pode ser muito útil, por exemplo, no caso de um relatório muito extenso: o usuário escolhe lá as opções e, ao invés de ficar esperando o EXE Pai processar o relatório, ele pode ir fazer outra coisa, já que o EXE Filho é quem vai ficar processamento o relatório, em background...
Estou precisando exatamente desse negócio para ir exibindo um relatório em TXT antes de este estar concluso.
Vc pode passar o caminho das pedras??
Jânio
fui...
e-mail:janioaguiar@yahoo.com.br
msn: janio_aguiar@hotmail.com
xHarbour1.2.1/Harbour3.2 + wvg + hwgui + Mediator + MySql
e-mail:janioaguiar@yahoo.com.br
msn: janio_aguiar@hotmail.com
xHarbour1.2.1/Harbour3.2 + wvg + hwgui + Mediator + MySql
Jânio, desculpe não responder antes, é que to meio na correria...
Seguinte: eu usei a OpenProcess porque a Startthread - que usa Multi Thread - não tava se entendendo com a ZIP.LIB, dava pau na compilação. Mas aí o Leonardo Sygecom entrou na jogada e matou a charada: retificou e me mandou uma nova LIB.
Bem, eu ainda não tive tempo de mudar (continuo usando a OpenProcess), mas me parece que a Thread é melhor, tem mais opções para controlar o que está sendo feito "por baixo do pano"... E eu vou passar pra ela! Mas, por enquanto, respondendo à sua pergunta, aqui vai um exemplo (resumido) de como eu uso a OpenProcess:
Seguinte: eu usei a OpenProcess porque a Startthread - que usa Multi Thread - não tava se entendendo com a ZIP.LIB, dava pau na compilação. Mas aí o Leonardo Sygecom entrou na jogada e matou a charada: retificou e me mandou uma nova LIB.
Bem, eu ainda não tive tempo de mudar (continuo usando a OpenProcess), mas me parece que a Thread é melhor, tem mais opções para controlar o que está sendo feito "por baixo do pano"... E eu vou passar pra ela! Mas, por enquanto, respondendo à sua pergunta, aqui vai um exemplo (resumido) de como eu uso a OpenProcess:
Código: Selecionar todos
* Programa PAI.exe
function main()
* parâmetro a enviar para FILHO.exe
arg=pad("Cliente"+codi+ctod(date()),100)
* incia execução do segundo EXE...
alca:=hb_openprocess(FILHO.exe,@nstdin,@nstdout,@nstderr)
if alca>0
* envia parâmetro para FILHO.exe
fwrite(nstdin,arg)
endi
Nota: nstdIN manda info pro FILHO (como acima), nstdOUT recebe e nstdERR checa se deu pau. Eu só uso a primeira...
*... continua a execução normal do PAI.exe
* na saída:
if !type("ALCA")=="U"
* se processo FILHO.exe foi iniciado...
if alca>0
* encerra FILHO.exe
hb_closeprocess(alca,.f.)
endi
endi
Código: Selecionar todos
* Programa FILHO.exe
function main()
#define fh_stdin 0
#define fh_stdout 1
#define fh_stderr 2
#include "fileio.ch"
priv linha
* pega parâmetro enviado pelo PAI.exe
linha=space(100)
fread(fh_stdin,@linha,len(linha))
* executa o que quiser em background...
* blablabla

