CPU 100% com o HARBOUR
Moderador: Moderadores
CPU 100% com o HARBOUR
Srs., Bom Dia!
Desenvolvi um programinha para gerar um arquivo .txt com uma sequencia de numeração. Esse arquivo .txt pode ter de 100 mil a mais de 1 milhão de numeros. Até aqui blz...o programa funciona corretamente.
O meu problema é q quando solicitado para gerar com uma qtde grande de numeros o CPU do PC fica em 100% e o programa parece travado, mas não está, esta executando. Até a régua de processamento fica travada. O que pode ser isso? Como posso resolver?
Abraço.
Desenvolvi um programinha para gerar um arquivo .txt com uma sequencia de numeração. Esse arquivo .txt pode ter de 100 mil a mais de 1 milhão de numeros. Até aqui blz...o programa funciona corretamente.
O meu problema é q quando solicitado para gerar com uma qtde grande de numeros o CPU do PC fica em 100% e o programa parece travado, mas não está, esta executando. Até a régua de processamento fica travada. O que pode ser isso? Como posso resolver?
Abraço.
- rochinha
- Administrador

- Mensagens: 4664
- Registrado em: 18 Ago 2003 20:43
- Localização: São Paulo - Brasil
- Contato:
Re: CPU 100% com o HARBOUR
Amiguinho,
isto vai depender de como sua rotina foi elaborada.
O código da mesma, se apresentado aqui no forum nos daria a informação mais exata para não termos de partir de suposições.
O processamento esta na lua porque voce esta escrevendo o arquivo enquanto gera.
O processamento pode produzir muita leitura e escrita enquanto é gerado.
O processamento é atrasado pelas rotinas que mostram o processamento sendo efetuado.
Solução:
Gerar estes numeros e preencher um vetor e depois descarregar este vetor de uma vez num arquivo.
Gerar a numeração gravando registros em um DBF depois gerar o arquivo TXT por SDF.
Gerar os numeros e salvá-los no arquivo TXT a cada 10%.
Em suma:
- Sem visualizar a rotina não podemos dar uma solução prática.
- Sem saber o objetivo da rotina ficamos sem saber se já existe alguma idéia pronta.
isto vai depender de como sua rotina foi elaborada.
O código da mesma, se apresentado aqui no forum nos daria a informação mais exata para não termos de partir de suposições.
O processamento esta na lua porque voce esta escrevendo o arquivo enquanto gera.
O processamento pode produzir muita leitura e escrita enquanto é gerado.
O processamento é atrasado pelas rotinas que mostram o processamento sendo efetuado.
Solução:
Gerar estes numeros e preencher um vetor e depois descarregar este vetor de uma vez num arquivo.
Gerar a numeração gravando registros em um DBF depois gerar o arquivo TXT por SDF.
Gerar os numeros e salvá-los no arquivo TXT a cada 10%.
Em suma:
- Sem visualizar a rotina não podemos dar uma solução prática.
- Sem saber o objetivo da rotina ficamos sem saber se já existe alguma idéia pronta.
OPS! LINK QUEBRADO? Veja ESTE TOPICO antes e caso não encontre ENVIE seu email com link do tópico para [url=mailto://fivolution@hotmail.com]fivolution@hotmail.com[/url]. Agradecido.
@braços : ? )
A justiça divina tarda mas não falha, enquanto que a justiça dos homens falha porque tarda.
@braços : ? )
A justiça divina tarda mas não falha, enquanto que a justiça dos homens falha porque tarda.
Re: CPU 100% com o HARBOUR
Rochinha,
O objetivo da rotinha é gerar o código verificador da numeração sequencial e gravar o numero + o verificar em .txt
Como vc podera ver abaixo, ja faço a a gravação inicialmente em DBF e somente depois gravo em TXT e mesmo enquanto esta gerando o DBF o CPU fica em 100%.
Fiz teste também com Array, mas não mudou nada.
Pode ser a rotina mesmo que necessite de processamento, devido aos cálculos neh.
Mas de qualquer forma, segue a rotina abaixo para que vcs possam visualiza-la:
Abraço.
O objetivo da rotinha é gerar o código verificador da numeração sequencial e gravar o numero + o verificar em .txt
Como vc podera ver abaixo, ja faço a a gravação inicialmente em DBF e somente depois gravo em TXT e mesmo enquanto esta gerando o DBF o CPU fica em 100%.
Fiz teste também com Array, mas não mudou nada.
Pode ser a rotina mesmo que necessite de processamento, devido aos cálculos neh.
Mas de qualquer forma, segue a rotina abaixo para que vcs possam visualiza-la:
Código: Selecionar todos
FUNCTION 2Col()
Peso:='8765432'
USE PRV
ZAP
for j=0 to Qt
a:=0
If Nm = 10000000
Nm := 5000000
Endif
Num:=alltrim(strzero(nm,7))
for t=1 to 8
sm1:=val(subs(num,t,1)) * val(subs(Peso,t,1))
a+=sm1
next
nm++
dg:=mod(a,11)
dg2:=11-dg
if j = qt1
dbgotop()
endif
if j < qt1
PRV->(dbappend())
PRV->campo1:=num+substr(Strzero(dg2,2),2,1)
else
PRV->campo2:=num+substr(Strzero(dg2,2),2,1)
skip
endif
Progress1()
next
Set alter on
Set alter to '2Col.txt'
dbgotop()
While !Eof()
? substr(campo1,1,8)+substr(campo2,1,8)
skip
Progress2()
Enddo
set alter to
Count to nREG
Digito.Label_1.Value:="Arquivo Gerado" + STR(nREG)
CLOSE
RETURN NiLAbraço.
- Pablo César
- Usuário Nível 7

- Mensagens: 5312
- Registrado em: 31 Mai 2006 10:22
- Localização: Curitiba - Paraná
CPU 100% com o HARBOUR
Levis, não esqueça de colocar o seu código sempre entre tags (code), eu ja corrigí pra você.
Eu acho que pode haver dois agravantes aí.
1. Tem necessidade de gravar em dbf ? Se puder evitar melhor, faça um contador, e grave diretamente no arquivo TXT em baixo nível.
2. As funções progress (1 e 2) acho que deve exibir em tela uma barra de progresso (como você mencionou), isto pode estar contribuindo seriamente a velocidade de execução do seu app., pois tendo a necessidade de mostrar em tela faz acesso IO (evite se puder para ganhar mais desempenho)
Eu acho que pode haver dois agravantes aí.
1. Tem necessidade de gravar em dbf ? Se puder evitar melhor, faça um contador, e grave diretamente no arquivo TXT em baixo nível.
2. As funções progress (1 e 2) acho que deve exibir em tela uma barra de progresso (como você mencionou), isto pode estar contribuindo seriamente a velocidade de execução do seu app., pois tendo a necessidade de mostrar em tela faz acesso IO (evite se puder para ganhar mais desempenho)
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.
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.
- rochinha
- Administrador

- Mensagens: 4664
- Registrado em: 18 Ago 2003 20:43
- Localização: São Paulo - Brasil
- Contato:
Re: CPU 100% com o HARBOUR
Amiguinho,
Então o problema pode estar na geração do arquivo.
Voce esta usando ? ... passe a usar função de baixo nivel como Fcreate(), FWrite e FClose() elas terão um consumo muito menor para isto.
Consulte mais informações de como usá-las.
Mude:
Por:
Então o problema pode estar na geração do arquivo.
Voce esta usando ? ... passe a usar função de baixo nivel como Fcreate(), FWrite e FClose() elas terão um consumo muito menor para isto.
Consulte mais informações de como usá-las.
Mude:
Código: Selecionar todos
...
next
Set alter on
Set alter to '2Col.txt'
dbgotop()
While !Eof()
? substr(campo1,1,8)+substr(campo2,1,8)
skip
Progress2()
Enddo
set alter to
Count to nREG
...
Código: Selecionar todos
...
next
ret_line := "chr(13)+chr(10)" // Set alter on
errhandle := FCREATE('2Col.txt') // Set alter to '2Col.txt'
dbgotop()
do While !Eof()
FWRITE(errhandle,substr(campo1,1,8)+substr(campo2,1,8)+&ret_line.) // ? substr(campo1,1,8)+substr(campo2,1,8)
skip
// Progress2()
Enddo
FCLOSE(errhandle) // set alter to
nREG := recco() // Count to nREG
...
OPS! LINK QUEBRADO? Veja ESTE TOPICO antes e caso não encontre ENVIE seu email com link do tópico para [url=mailto://fivolution@hotmail.com]fivolution@hotmail.com[/url]. Agradecido.
@braços : ? )
A justiça divina tarda mas não falha, enquanto que a justiça dos homens falha porque tarda.
@braços : ? )
A justiça divina tarda mas não falha, enquanto que a justiça dos homens falha porque tarda.
- Pablo César
- Usuário Nível 7

- Mensagens: 5312
- Registrado em: 31 Mai 2006 10:22
- Localização: Curitiba - Paraná
CPU 100% com o HARBOUR
Aliás, você pode exibir, mas não de um a um, quem sabe de 100 em 100 ou 1000 em 1000. Dependerá a quantidade total de itens, você pode testar a gosto. Podendo até criar uma escala que dependendo o numero de itens você exiba (10, 100, 1000...) daí você dará uma folga pro processador e ainda deixará pro usuário a sensação de movimento.mostrar em tela faz acesso IO (evite se puder para ganhar mais desempenho)
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.
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.
Re: CPU 100% com o HARBOUR
Srs., Bom Dia!
Fiz todas as alterações descritas, utilizando as funções de baixo nível e eliminando a barra de progresso, mas não mudou nda, o CPU continua em 100%.
Fiz todas as alterações descritas, utilizando as funções de baixo nível e eliminando a barra de progresso, mas não mudou nda, o CPU continua em 100%.
- Pablo César
- Usuário Nível 7

- Mensagens: 5312
- Registrado em: 31 Mai 2006 10:22
- Localização: Curitiba - Paraná
CPU 100% com o HARBOUR
Mostre como ficou seu novo código.
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.
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.
Re: CPU 100% com o HARBOUR
Ficou da seguinte forma:
Código: Selecionar todos
FUNCTION 2Col()
Peso:='8765432'
USE PRV
ZAP
if Nmf = 0
for j=0 to Qt
a:=0
If Nm = 10000000
Nm := 5000000
Endif
Num:=alltrim(strzero(nm,7))
for t=1 to 8
sm1:=val(subs(num,t,1)) * val(subs(Peso,t,1))
a+=sm1
next
nm++
dg:=mod(a,11)
dg2:=11-dg
if j = qt1
dbgotop()
endif
if j < qt1
PRV->(dbappend())
PRV->campo1:=num+substr(Strzero(dg2,2),2,1)
else
PRV->campo2:=num+substr(Strzero(dg2,2),2,1)
skip
endif
//Progress1()
next
ret_line := "chr(13)+chr(10)" // Set alter on
errhandle := FCREATE('2Col.txt') // Set alter to '2Col.txt'
dbgotop()
do While !Eof()
FWRITE(errhandle,substr(campo1,1,8)+substr(campo2,1,8)+&ret_line.) // ? substr(campo1,1,8)+substr(campo2,1,8)
skip
//Progress2()
Enddo
FCLOSE(errhandle) // set alter to
nREG := recco() // Count to nREG
Digito.Label_1.Value:="Arquivo Gerado" + STR(nREG)- Pablo César
- Usuário Nível 7

- Mensagens: 5312
- Registrado em: 31 Mai 2006 10:22
- Localização: Curitiba - Paraná
CPU 100% com o HARBOUR
Levis, a idéia seria também eliminar o acesso a gravação do dbf que você está usando-o de forma temporária. Pelo que entendí você precisa do primeiro registro e ultimo. Eu diria de você guardar em variáveis esse valor e descarregando linha a linha com FWRITE diretamente no arquivo texto a ser gerado. Também não entendí direito (pois desconheço variaveis qt e qt1) talvez seria substituido o primeiro registro ? Se for então, trabalhe diretamente com as variáveis (inicio e ultimo) e somente ao finalizar o processo, você irá descarregar no arquivo em forma de substituição. Seria isso ?
Qual é a função de qt1 ?
O quê é nm ? variavel que é passado por parâmetro é um campo que contém o quê ?
Crie variavel contador, para saber quantas linhas (ou registros) estão sendo gravados.
Se em vez de ser qt1 você quis dizer qt e qt é o parâmetro passado que define quantidade a ser processado, então tenho outra pergunta:
Para que serve você ir para gotop na segunda volta do looping (pois você começo com zero), se depois dessa linha você está colocando uma condição: if j < qt1 e neste caso quase sempre será menor a não ser que qt1 ou qt é a ultima volta limte.
As funções de baixo nível estariam no lugar errado se você eliminar o dbf, pois não precisa varrer um dbf para criar o arquivo texto, pode ir gerando.
Estou tentando exugar seu código, mas com erros fica dificil, não sei também se está completo...
Qual é a função de qt1 ?
O quê é nm ? variavel que é passado por parâmetro é um campo que contém o quê ?
Crie variavel contador, para saber quantas linhas (ou registros) estão sendo gravados.
Se em vez de ser qt1 você quis dizer qt e qt é o parâmetro passado que define quantidade a ser processado, então tenho outra pergunta:
Para que serve você ir para gotop na segunda volta do looping (pois você começo com zero), se depois dessa linha você está colocando uma condição: if j < qt1 e neste caso quase sempre será menor a não ser que qt1 ou qt é a ultima volta limte.
As funções de baixo nível estariam no lugar errado se você eliminar o dbf, pois não precisa varrer um dbf para criar o arquivo texto, pode ir gerando.
Estou tentando exugar seu código, mas com erros fica dificil, não sei também se está completo...
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.
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.
- Itamar M. Lins Jr.
- Administrador

- Mensagens: 7929
- Registrado em: 30 Mai 2007 11:31
- Localização: Ilheus Bahia
- Curtiu: 1 vez
Re: CPU 100% com o HARBOUR
Ola!
Use:
Para liberar o processador.
Se usar a Hwgui
Saudações,
Itamar M. Lins Jr.
Use:
Código: Selecionar todos
milisec()
//ou
inkey(.1)
Se usar a Hwgui
Código: Selecionar todos
Do While
hwg_processmessage()
EndDo
Itamar M. Lins Jr.
Saudações,
Itamar M. Lins Jr.
Itamar M. Lins Jr.
Re: CPU 100% com o HARBOUR
Exatamente! Um delay no meio do loop pára o processamento e dá folga suficiente para o escalonador do Windows trocar de tarefa, permitindo que outros processos concorrentes também usem a CPU. Pode parecer estranho, mas só esse delay já deve fazer o percentual de CPU diminuir.
Agora, se a tela do programa "congelar", talvez seja necessário também fazer a fila de mensagens do Windows receber alguma atenção. Daí será necessário algo do tipo ProcessMessage()¹ do Delphi. Ou essa tal função hwg_processmessage() da HWGUI que, pelo nome, não parece ser feita para liberar o processador, mas para dar foco à fila de mensagens.
Note que são duas coisas diferentes: o tempo extra para o escalonador do Windows poder atuar e o esvaziamento da fila de mensagens para evitar congelamentos, que podem ocorrer mesmo em sistemas que consomem pouca CPU.
Uma alternativa (bem) mais elaborada, para sistemas multicore, seria colocar a tarefa numa thread à parte e modificar a máscara de afinididade de processador para forçar a execução dessa thread em um core específico (ou em mais de um). Mas pelo trabalho que dá, a tarefa em si tem de ser realmente muito importante. Do contrário, não compensa.
¹ Essa função pára a aplicação e processa sua fila de mensagens até que ela esteja vazia, quando então o controle retorna à execução normal. Se a fila travar, mensagens do tipo "REPAINT", que desenham uma barra de progresso, por exemplo, ficam congelados.
Agora, se a tela do programa "congelar", talvez seja necessário também fazer a fila de mensagens do Windows receber alguma atenção. Daí será necessário algo do tipo ProcessMessage()¹ do Delphi. Ou essa tal função hwg_processmessage() da HWGUI que, pelo nome, não parece ser feita para liberar o processador, mas para dar foco à fila de mensagens.
Note que são duas coisas diferentes: o tempo extra para o escalonador do Windows poder atuar e o esvaziamento da fila de mensagens para evitar congelamentos, que podem ocorrer mesmo em sistemas que consomem pouca CPU.
Uma alternativa (bem) mais elaborada, para sistemas multicore, seria colocar a tarefa numa thread à parte e modificar a máscara de afinididade de processador para forçar a execução dessa thread em um core específico (ou em mais de um). Mas pelo trabalho que dá, a tarefa em si tem de ser realmente muito importante. Do contrário, não compensa.
¹ Essa função pára a aplicação e processa sua fila de mensagens até que ela esteja vazia, quando então o controle retorna à execução normal. Se a fila travar, mensagens do tipo "REPAINT", que desenham uma barra de progresso, por exemplo, ficam congelados.
[]'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!
Re: CPU 100% com o HARBOUR
Código: Selecionar todos
milisec()
//ou
Do While
hwg_processmessage()
EndDo
Já o
Código: Selecionar todos
inkey(.1)Re: CPU 100% com o HARBOUR
O colega se distraiu e escreveu o nome errado. O correto é Millisec() que é, aliás, uma opção melhor, já que Inkey(0.1) significa 1/10 de segundo. Um tempo meio alto. Tente 1 ms. Se não der, vá aumentando.
[]'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!
- sygecom
- Administrador

- Mensagens: 7131
- Registrado em: 21 Jul 2006 10:12
- Localização: Alvorada-RS
- Contato:
Re: CPU 100% com o HARBOUR
Qual versão do Harbour ?
Em vez de:
hwg_processmessage() // deve ser usado somente com Hwgui conforme o colega acima falou
use:
gtProcessMessages() ou NextKey()
Em vez de:
hwg_processmessage() // deve ser usado somente com Hwgui conforme o colega acima falou
use:
gtProcessMessages() ou NextKey()
Leonardo Machado
xHarbour.org + Hwgui + PostgreSql
xHarbour.org + Hwgui + PostgreSql

