Vamos discutir sobre THREAD ?

Delphi

23/01/2004

Pessoal, proponho que neste topico possamos discutir sobre thread algo meio obscuro para muitas pessoas, e que talvez com um pouco de informações de todos possamos sanar a duvida de muitos.


Icheuk

Icheuk

Curtidas 0

Respostas

Icheuk

Icheuk

23/01/2004

Bom vou abrir a lista:

Trocando email com outro associado do clubedelphi, surgiu uma duvida pois ao fechar uma thread nos podemos fecha-la com

MinhaThread.Terminate;

E ele falou que seria necessario colocar o

MinhaThread.Free;

E a informação que tenho é que quando o
OnFreeTerminate := True;

Entao a propria thread executa o free, alguem tem alguma informação sobre isto ou outra coisa a respeito de thread pode ser até duvida.

Proponho que nesta oportunidade fornecida pela comunidade Clubedelphi de nos proporcionar este espaço vomos colocar aqui todas as nossas duvidas sobre thread e informações por mais simples que sejam, eu vou tentar ajudar a levantar todos os aspectos, pois estou trabalhando com threads e achei fantastica, e gostaria de levantar todas as informacoes possiveis e assim desmistificar o que é thread, que acredito eu ser muito importante para todos, pois acho que todos um dia ja precisaram desenvolver algo que fosse processado sem parar o andamento do sistema.

Conto com a colaboração de todos.

Um grande abraço a todos, e vamos começar!

Ivan Cheuk


GOSTEI 0
Paulo

Paulo

23/01/2004

Concordo com vc Ivan, pois poucos trabalham com Thread, por desconhecerem. Thread´s, Processos e etc... São coisas que todos deveriamos estar dominando pelo tempo de programação que muitos já possuem. Um curso de delphi é caro(falo de um bom curso). Então a solucão barata e ótima é este forum.


GOSTEI 0
Icheuk

Icheuk

23/01/2004

Legal paulo e ai voce ja trabalhou com thread, ja fez alguma coisa, ja leu sobre thread?


GOSTEI 0
Icheuk

Icheuk

23/01/2004

Ei pessoal, pelo indice do forum ja entraram varias pessoas, vamos responder colocar aspectos de thread em discussao, estou esperando, vamos la, vamos juntos desvendar thread !

Ivan Cheuk


GOSTEI 0
Icheuk

Icheuk

23/01/2004

Na questao sobre o Free, eu fiz alguns testes e todas as vezes que eu coloco OnFreeTerminate := True e tento colocar ao fechar a thread
MinhaThread.Terminate;
MinhaThread.Free;

Quando executa o free acontece uma exception, acredito eu que ao ter
OnFreeTerminate como True a propria thread executa o Free.

Alguem teria alguma informação a respeito.

Ou outra duvida ou qualquer coisa que seja a respeito de Thread, nao fiquem acanhados de perguntar vamos gerar as respostas juntos, alguem tem duvido do que é Thread?


GOSTEI 0
Icheuk

Icheuk

23/01/2004

po pessoal, ja entrou um monte de pessoas mas ninguem responde porque?

Se a pessoa sabe mais do que foi discutido aqui entao poderia responder para passar mais algumas informacoes.

Mas se caso a pessoa nao sabe nada ou nao sabe muito entao deve ter duvidas, logo tera perguntas entao vamos postar as dicas ou as perguntas, vamos la estou esperando.

Segue abaixo um texto sobre thread bem interessante:

Hoje vamos falar um pouco sobre sincronia de processos usando a classe TThread
fornecida pelo Delphi que permite fazer o controle dos processos em nossos
sistemas.

No nosso dia-a-dia surgem situações em que uma determinada tarefa não pode
esperar que outra tarefa seja terminada por completo para iniciar, sendo assim,
precisamos ter mais de um processo sendo executado pelo processador
simultaneamente. Quando estamos trabalhando com processamento paralelo tudo bem,
caso contrário, temos que usar técnicas de sincronismo para torna isso possível.

A classe TThread é uma classe abstrata, por isso nunca é utilizada diretamente e
sim através de uma subclasse dela, que por sua vez utiliza recursos da classe
base, neste caso a TThread.

Vejamos a seguir um exemplo clássico de representação de Thread, onde
trabalharemos com um formulário, três barras de progresso, que representarão o
multiprocessamento e, dois botões de comandos básicos. A tela fica algo parecido
como a seguinte:

Temos nessa nossa pequena aplicação duas procedures:

· AdicionarProgresso(Barra: TProgressBar) – para adicionar progressos a barra de
progresso passada como parâmetro até ser completada;
· TForm1.Button1Click(Sender: TObject) – para iniciar o preenchimento das
barras.

Veja o código a seguir de cada uma delas:

procedure AdcionarProgresso(Barra: TProgressBar);
begin
while Barra.Position < Barra.Max do
Barra.StepBy(1);
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
ProgressBar1.Position := 0;
ProgressBar2.Position := 0;
ProgressBar3.Position := 0;
AdcionarProgresso(ProgressBar1);
AdcionarProgresso(ProgressBar2);
AdcionarProgresso(ProgressBar3);
end;

Rode a aplicação e observe o resultado.
Veja que cada ProgressBar atualiza o valor da propriedade Position
individualmente, ou seja, somente após a conclusão do preenchimento a primeira
ProgressBar é que a segunda inicia seu preenchimento e o preenchimento da
terceira, conseqüentemente, só depois da segunda ter sido totalmente preenchida.

Para que possamos fazer com que as barras sejam preenchidas simultaneamente,
devamos usar o conceito de Threads.

Varemos como fazer isso na próxima semana. Até lá!

Um abraço.







Usando Threads – Parte Final
Número da coluna: 21
Data: 24/06/2003

Olá pessoal.

Vamos dar continuidade ao assunto de Threads que demos início na coluna
anterior.

Como já vimos, a classe TThread é uma classe abstrata, não podendo ser utilizada
diretamente e sim através de uma subclasse dela. Temos, assim, a necessidade de
derivar uma nova classe, tendo como classe base a classe TThread e, então,
implementar o método Execute.

Vamos por isso em prática:

1. Selecione o menu File | New | Other;
2. Selecione Thread Object na guia New conforme a figura abaixo;



3. Será então exibida uma nova janela New Thread Object, onde deve ser digitado
o nome da classe que representa nosso novo processo. Se você estiver usando o
Delphi 7 será exibida uma janela igual a seguinte, onde deve ser preenchido
apenas o campo Class Name, caso esteja utilizando uma versão anterior será
exibida alguma janela semelhante



4. Será então gerada um esqueleto com a unidade da nossa nova classe.

A definição do método Execute é tão importante que foi gerada automaticamente,
assim como também um comentário que o ajuda a implementar o método, comentário
este que, evidentemente, pode ser retirado sem nenhum problema.

Este comentário ainda nos informa que alterações de propriedades e chamadas de
métodos aos componentes da VCL (Visual Component Library), somente podem ser
feitas mediante o método Synchronize. Sendo assim qualquer método que altere uma
propriedade de um objeto da VCL deve ser chamado passando seu nome como
parâmetro do método Synchronize da nova classe.

Vejamos a seguir como ficam as unidades prontas com seus respectivos comandos:

Unidade do Formulário

unit Unit1;

interface

uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, ComCtrls;

type
TForm1 = class(TForm)
ProgressBar1: TProgressBar;
ProgressBar2: TProgressBar;
ProgressBar3: TProgressBar;
Label1: TLabel;
Label2: TLabel;
Label3: TLabel;
Button1: TButton;
Button2: TButton;
procedure Button1Click(Sender: TObject);
procedure Button2Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;

var
Form1: TForm1;

implementation

uses Unit2;

{$R *.dfm}

procedure AdcionarProgresso(Barra: TProgressBar);
begin
while Barra.Position < Barra.Max do
Barra.StepBy(1);
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
ProgressBar1.Position := 0;
ProgressBar2.Position := 0;
ProgressBar3.Position := 0;
AdcionarProgresso(ProgressBar1);
AdcionarProgresso(ProgressBar2);
AdcionarProgresso(ProgressBar3);
end;

procedure TForm1.Button2Click(Sender: TObject);
var Barra1, Barra2, Barra3: TMeuThread;
begin
ProgressBar1.Position := 0;
ProgressBar2.Position := 0;
ProgressBar3.Position := 0;
Barra1 := TMeuThread.Criar(ProgressBar1);
Barra2 := TMeuThread.Criar(ProgressBar2);
Barra3 := TMeuThread.Criar(ProgressBar3);
end;

end.

Unidade do Thread

unit Unit2;

interface

uses
Classes, ComCtrls;

type
TMeuThread = class(TThread)
private
BarraProgresso: TProgressBar;
protected
procedure Execute; override;
procedure Incrementa;
public
constructor Criar(Barra: TProgressBar);
end;

implementation

constructor TMeuThread.Criar(Barra: TProgressBar);
begin
Create(False);
BarraProgresso := Barra;
FreeOnTerminate := True;
end;

procedure TMeuThread.Execute;
begin
while BarraProgresso.Position < BarraProgresso.Max do
Synchronize(Incrementa);
end;

procedure TMeuThread.Incrementa;
begin
BarraProgresso.StepBy(1);
end;

end.


GOSTEI 0
Vanius

Vanius

23/01/2004

Nao tenho experiencia com Threads, mas quero aprender.
Parece q vc consegue executar duas ou mais coisas ao mesmo tempo.
Algo q aprendi, ´meio´ parecido com isto (de certa forma) é q colocando o Application.ProcessMessage; no meio de loops, whiles, ou rotinas q ´demoram´, sempre q o user apertar Ctrl+Alt+Del, seu prog. sempre continuará mostrando ´executando´ ao invés de ´nao respondendo´.


Um amigo me enviou um exemplo de como trabalhar. No Delphi 3 e 5 tambem temos exemplos. c:\(pasta delphi)\exemples\Thread.

Se vcs puderem enviar mais exemplos, ficarei muito agradecido.

Abraços,


Vanius


GOSTEI 0
Icheuk

Icheuk

23/01/2004

Legal, vanius.

O conceito de thread é o seguinte:

Se voce tiver uma maquina com mais de um processador e trabalhar com thread, cada thread que voce executar vai para um processador, ou seja é o mesmo conceito do windows multi-processado, porem como a grande maioria trabalha com maquinas com um unico processador apenas usamos o conceito de multi-tarefas, ou seja cada thread vai concorrer por um tempo de processador, sendo assim nos temos como dar prioridades para determinadas threads e tirar a prioridade de outras, e desta forma nossa aplicacao nunca fica parada pois mesmo com sistemas administrativos, acredito eu que todos ja tiveram aquelas rotinas que acabam demorando muito e o micro fica parado, ou um relatorio, desta forma podemos executar a tarefa em uma thread e deixar a aplicacao livre para o usuario continuar a trabalhar e no final o micro pode informar o mesmo que a tarefa ja foi concluida, ufa, acho que é isto, alguem saberia me dizer se em uma rede a thread é rodada no servidor ou local ou se temos condições de definir o local de execução da mesma ?

Legal vanius, vamos continuar o debate, acredito eu que seja desta forma que vamos juntos desenvolver melhores conhecimentos de determinadas propriedades desta ferramenta fantastica chamada Delphi.

ICheuk


GOSTEI 0
Icheuk

Icheuk

23/01/2004

E ai galera, bom dia e boa semana a todos, e entao vamos continuar a falar sobre thread.

Continuo aguardando, ok.

ICheuk


GOSTEI 0
Icheuk

Icheuk

23/01/2004

:cry: E ai pessoal, ninguem quer discutir sobre thread :?: :cry:

:(


GOSTEI 0
Icheuk

Icheuk

23/01/2004

Bom pessoal, pelo visto ninguem quer discutir sobre thread entao eu estou parando de monitorar o topico.

Agradeço a todos pela ajuda e qualquer coisa me mande um email.

ICheuk


GOSTEI 0
Osocram

Osocram

23/01/2004

AEeeee

Fiquei um bom tempo sem aparece no forum ... estou voltando agora...

Bom sobre isso eu naum sei mto... mas gostaria d aprender tbm...

Achei interessante o ex. acima...

Bom.. gostaria d falar p naum desistir... sempre q alguem tiver algum ideia continuar postando aqui... eu vou comecar a mecher tbm..


GOSTEI 0
Osocram

Osocram

23/01/2004

Aproveitando o topico...
sera q naum tem como eu aproveitar uma unit do meu prog q funca normal p fazer funcar em multiThread?

ahh vou ver se acho um fonte q eu tinha aqui c multiThread. dae eu posto aqui o fonte.


GOSTEI 0
Kroki

Kroki

23/01/2004

To com um problemao.
Estou usando o Demo do delphi sobre chat na net usando Thread.
Alguem sabe oque preciso implementar para quando eu enviar uma messangem pra um IP e esse IP nao estiver disponivel,meu programa nao ficar ´travado´esperando uma resposta?
Se alguem nao entendeu,é só usar o demo do NetChat e mandar algo para um IP nao exeistente.


GOSTEI 0
Osocram

Osocram

23/01/2004

ve se naum tem uma propriedade ´timeout´... isso faz c q vc se desconecte depois d tanto tempo ocioso.


GOSTEI 0
Kroki

Kroki

23/01/2004

Nao achei essa propriedade.
Alguem tem mais alguma ideia?


GOSTEI 0
Icheuk

Icheuk

23/01/2004

:lol: Estou de volta!!!! :D :D

Legal osocram, pelo seu opoio.

Mudar uma unit eu nao sei se da, mas voce pode copiar as procedures da unit em uma nova thread, respeitando as regras da mesma.

Poste a unit ou as procedures ou apenas as duvidas e vamos debater a melhor forma de fazer, desta forma quem sabe incentiva o pessoal a começar a discutir sobre thread.

ICheuk


GOSTEI 0
Icheuk

Icheuk

23/01/2004

Kroki.

Como é o processo que voce executa, voce ?

Voce fica com uma thread aberta o tempo todo e esta fica incumbida de mandar mensagens para um IP ?

Ou voce abre uma thread para mandar uma mensagem e no final fecha a thread, ou seja é uma thread para todas as mensagens ou uma thread por cada mensagem?

ICheuk


GOSTEI 0
Kroki

Kroki

23/01/2004

Icheuk,eu estou usando o exemplo do Delphi(NetChat):procedure TForm1.Button5Click(Sender: TObject);
begin
TcpClient1.RemoteHost :=teste;
TcpClient1.RemotePort :=´4000´;
try
if TcpClient1.Connect then
TcpClient1.Sendln(´Ufa ate que enfim!´);
finally
TcpClient1.Disconnect;
end;
end;

Se teste nao estiver presente,fica em looping infinito(acho..).


GOSTEI 0
Icheuk

Icheuk

23/01/2004

Kroki, esta procedure esta dentro de uma thread ?

Eu nao sei a solucao mas talvez a saida e voce criar um novo topico perguntado ´Como verificar se um IP existe na rede´.

Ai voce verificaria a existencia do ip em caso afirmativo ai sim voce executa a procedure, mas vou tentar perquisar e se achar algo lhe envio.

Dentro desta aplicacao aonde e como voce usa thread ?

ICheuk


GOSTEI 0
Osocram

Osocram

23/01/2004

ond esta a thread ae?


GOSTEI 0
Icheuk

Icheuk

23/01/2004

osocram, e ai tudo bem.

O que esta desenvolvendo em thread ?

ICheuk


GOSTEI 0
Kroki

Kroki

23/01/2004

Nao entendi?Vcs nao tem o Demo do delphi com o net chat?
Nao podem olhar a fonte?


GOSTEI 0
Icheuk

Icheuk

23/01/2004

Nao entendi?Vcs nao tem o Demo do delphi com o net chat?
Nao podem olhar a fonte?


O que nao entendeu ?

Nao eu nao tenho o Demo do delphi com o net chat !

Este topico é para esplorarmos a funcionalidade de Thread e por isto a pergunta sobre thread ?

Refazendo a pergunta e que ponto do sistema esta a thread ?

ICheuk


GOSTEI 0
Osocram

Osocram

23/01/2004

Ae ICheuk

Seguinte.... eu tava tentando entender o ex. q foi dado acima...
vi q no delphi tem um ex. tbm...

Ainda naum tive tempo p dedicar a isso p me aprofundar um pouco mais... isso eu vejo c o tempo...

Ok.. eu tava tentando entender.... Como as thread teoricamente funcionam em paralelo... eu naum posso colocar 2 funcoes q dependem uma dah outra em thread diferentes, neh?

E eu tava tentando pensar como eu faria p agilizar um prog comercial... eu trabalho c programas comerciais... e queria dar uma agilizadas neles....

Ps:. eu ainda naum comecei a programar nada c thread..


GOSTEI 0
Icheuk

Icheuk

23/01/2004

Tudo bem osocram, espero que sim.

Bom o conceito de thread como foi dito nos itens do topico, a thread na realidade seria processamento paralelo ou seja quando trabalhar com mais de um processador ai sim voce teria uma grande performance pois ao executar duas threads, a primeira é executado no processador 1 e a segunda no processador 2, porem como na maioria dos casos trabalhamos com maquinas potentes porem com apenas um processador entao utilizamos o mesmo conceito do windows que é trabalhar com multi-tarefas, ou seja para cada tarefa ele ocupa um espaco do processador ou seja como se fosse uma fila e quebra o processo em varios blocos ai vai processando o bloco 1 da tarefa 1, depois o bloco 1 da tarefa 2, bloco 1 da tarefa 3, bloco 2 da tarefa 1, e assim por diante.

Quando trabalhamos com o nosso sistema sem threads este apenas processa o que estiver na sequencia que deve ser como o seu sistema trabalha, sendo assim voce pode pegar os processos mais criticos de sua aplicacao(processo aquele que demora para ser rodado e deixa o operador ficar esperando e ate brincar que vai tomar um cafe e volta depois para ver se esta terminado), este processo poderia ser transformado em uma thread e o operador poderia executar a tarefa e comecar a fazer outra tarefa no sistema enquanto que a primeira tarefa é rodada paralelamente sem travar a operacao do sistema ( o termo paralelamente é apenas simbolico como foi explicado acima pois nos da a impressao que sao varios processos rodando ao mesmo tempo mas na realidade sao pacotinhos em fila, ok).

Bom depois desta esplicação vamos a sua pergunta, voce ate poderia ter duas threads e uma dependendo do resultado da outra so que teria que ser alguma coisa bem pensada para que nao provoque uma travada no sistema.

Ex. o primeiro processo esta na Thread1, assim como o segundo esta na thread2 e aguardando o resultado da thread1, a thread1 deve processar alguma coisa e gerar um registro em uma tabela temporaria em memoria e a thread2 fica lendo esta tabela e ao chegar o registro a thread2 processa o mesmo e gera os resultados necessarios.

Este exemplo tem outras formas de se resolver porem esta foi a que me veio primeiro na cabeça, para que seja encontrado a melhor solução precisamos conhecer melhor o problema.

Espero ter contribuido.

Fico no aguardo.

ICheuk


GOSTEI 0
Osocram

Osocram

23/01/2004

Uiaaaa jah aprendi bem os conceitos... eu tinha uma ideia d como eles funcionavam mas naum tinha certeza... agora vc esclareceu..

Bom... eu tenho um ex.

eu tenho um relatorio enorme... enorme mesmo.... tenho q executar 3 sqls q tem join d tres tabelas.... e ainda somar os resultados delas... e no final juntar essas 3 sqls

Bom... eu fiz eles.. mas estaum c uns errinhos inda.. e demora quase um minuto tipo comparado c os outros relatorios q eu fiz isso eh mto...
Dae por forca maior eu tive q largar isso d lado e terminar outras coisas primeiro.... naum sei qdo volto nele.. mas eu tava pensando no seguinte...
Separar os 3 sqls em tabelas virtuais, cada um em uma thread e depois soma-las...

Isso eh possivel, neh?


GOSTEI 0
Icheuk

Icheuk

23/01/2004

Sim, acho que é possivel, porém é necessario analisar bem o problema para chamar todas as threads e a ultima saber quando cada uma das anteriores terminou, ok !

ICheuk


GOSTEI 0
Osocram

Osocram

23/01/2004

Blz...
bom gostaria d testar as threads... em progs simples.. q nem vc fez c o ex acima...

Estou testando ele agora...

Preciso entender bem oq foi feito lah... ateh q naum eh taum complicado..
por enqto


GOSTEI 0
Icheuk

Icheuk

23/01/2004

não se esqueça do metodo syncronized este serve para voce executar uma procedure que atualiza qualquer componente visual da sua VCL.

Ou seja todo o processamento voce executa dentro da procedure principal criada automaticamente pela thread e quando for atualizar alguma coisa visual voce utiliza o metodo syncronized(SuaProcedure);

Ok.

ICheuk


GOSTEI 0
Osocram

Osocram

23/01/2004

acho q to entendendo... vamos fazer um outro prog simples so q um pouco mais complexo q esse primeiro....

Vou pensar em algo... se vc tiver alguma ideia fala ae...


GOSTEI 0
Icheuk

Icheuk

23/01/2004

Pegue um exemplo do seu proprio programa e tente fazer, e vamos debatendo as duvidas, ok

ICheuk


GOSTEI 0
Osocram

Osocram

23/01/2004

Por mim td bem.. mas eu naum consigo pensar ond no prog poderia se usar isso.... estou desd ontem pensando

ehheeh acho q to mto devagar.
Mas espera um pouco q ainda to pensando.

(mas eu tava pensando em outra coisa tbm... isso seria mto util em jogos)


GOSTEI 0
Osocram

Osocram

23/01/2004

q tal isso?

No FCad (form cadastro)
eu tenho no OnShow
- zeramento de variaveis
- desparar a consulta SQL q vai trazer os registro jah cadastrados
- e a configuracao padrao do formulario...

isso aqui eu poderia separar os 3 cada um em uma thread?


GOSTEI 0
Icheuk

Icheuk

23/01/2004

legal, porem esta tarefa deve ser bem rapida e nao possibilitaria com que o usuario operace o sistema enquanto a thread é executada.

Ai no seu sistema nao tem nenhum processo que o usuario aperte um botao qualquer e fique esperando o retorno de alguma coisa.

ICheuk


GOSTEI 0
Osocram

Osocram

23/01/2004

Esse q eu falei eh um caso...
olha soh...
o cliente vai no menu principal e manda abri o FromCad...
dae ele tem q esperar todas aquelas coisas serem executadas p q ee possa mexer...

Ve se isso serve.. enqto isso vou pensando em algo mais..


GOSTEI 0
Icheuk

Icheuk

23/01/2004

Acho que nao pois pelo que entendi, ao abrir o seu form o usuario quer efetuar alguma tarefa e este form deve executar algumas querys para liberar o form para a atividade, portanto independente de ser em thread ou nao ele vai ter que esperar (se eu entendi direito).

Porem é bem legal aplicar em uma atividade que voce inicia e pode continuar fazendo outra atividade enquanto esta fica pronta.

ICheuk


GOSTEI 0
Osocram

Osocram

23/01/2004

Ah tah... vc tah certo.. o user vai ter q esperar...


GOSTEI 0
Osocram

Osocram

23/01/2004

Achei isso no site
[url]http://www.unidev.com.br/artigos/delphithreads000.asp?id=346[/url]


Priority: (tpIdle, tpLowest, tpLower, tpNormal, tpHigher, tpHighest, tpTimeCritical)

Ond ele pod ser usando assim

Constructor MeuThread.create;
Begin
Inherited Create(True);
Priority:= tpNormal; {No windows}
FreeOnTerminate:=True;
Resume;
End;


GOSTEI 0
Icheuk

Icheuk

23/01/2004

Fala osocram, beleza.

Eu nao entendi muito bem o que voce escreveu, porem pelo que entendi.

O comando priority, quer dizer prioridade da thread e dentro do parenteses os tipos de prioridades, desta forma voce pode indicar que tem a preferencia do processador na hora de executar uma tarefa, caso esta terefa seja mais critica voce pode elevar a sua prioridade e esta deve ter preferencia no processador.

E a forma de usar que voce passou, e esta mesmo, esta correto no seu exemplo.

Porem a minha duvida é se eu posso mudar a prioridade de uma thread no meio de um processamento, ou se apenas posso informar a prioridade na criação da mesma ?

Caso saiba ou consiga a informação eu agradeço, e vou fazer alguns testes assim que possivel e caso obtenha resultado lhe informo.

E para os outros usuarios que estao lendo este topico, participem deem sua opiniao, vamos discutir sobre thread, vamos aprender juntos, fico no aguardo de suas opinioes.

ICheuk


GOSTEI 0
Osocram

Osocram

23/01/2004

Ae...

Bom eh isso mesmo q vc entendeu.. ele funca como prioridade...

Eu naum testei mudar em tempo d execucao.. mas acho q pod ser possivel sim.... mas naum sei se o ruindows aceitaria...
heheheheh

Acho q o ruindows se perderia....


GOSTEI 0
Icheuk

Icheuk

23/01/2004

Nao acredito que o windows ira ter problemas com a prioridade, pois é apenas uma ordem na fila.

Mas bem legal o exemplo.

A todos

E ai pessoal, sei que estao entrando e lendo, vamos postar mais assuntos sobre thread, temos varias perguntas a responder ainda, qual a melhor maneira de terminar uma thread ( fechar ) ou entao reinicializada, como posso contar as threads que estao ativas no momento.


Todas sao perguntas muito importantes do processo.

Fico no aguardo para discutirmos estes e outros temas sobre thread.

ICheuk


GOSTEI 0
Osocram

Osocram

23/01/2004

Bemm essa semana esta bem corrida... so vou poder testar as coisas no fds...

Mas tive pensando em uma coisa.... se eu fazer um prog q executa alguns progs do meu pc, por ex: Icq, Delphi, Winamp... dae eu vou deixar p configurar os progs q eu quero... dae qdo apertar no botaum... ele executar os 3 progs mas ao mesmo tempo deixe eu ir fazendo as minhas outras coisas...

Sera q ajuda em alguma coisa usar thread ae?

pq qdo eu ligo i icq e mando ligar o delphi.. Meu Deus... demoraaaaaa...
e tenho q ficar esperando... pq td fica be


GOSTEI 0
Icheuk

Icheuk

23/01/2004

Osocram

Acho que neste caso nao deve funcionar como deveria pois para chamar o programa sitado por voce, ou qualquer que seja o programa voce deve chamalo por api do window e neste caso o programa aloca a memoria e processador que ele necessita e da meneira como foi programado, e o windows que mantem o controle sobre a aplicacao, quando somos nos que desenvolvemos podemos controlar tao aplicacao, sendo assim voce pode ate testar no final de semana mas acredito eu que nao teria muita serventia, sabendo que estas aplicacoes poderiam estar no iniciar do proprio windows, e acredito eu que voce nao vai conseguir nem melhorar o tempo e nem controlar corretamente nemhuma das aplicacoes.

ICheuk


GOSTEI 0
Cicerojr

Cicerojr

23/01/2004

Bom Galera,

Adorei este tópico, pois naum tinha nem idéia de q isto poderia ser feito e a prova de que gostei muito é q decidi implementá-la nas minhas aplicações. Porém gostaria de tirar uma dúvida com relação ao tempo em que cada thread vai ter do precessador .. é possível determiná-lo .. ou este tempo varia de acordo com a prioridade ??

Valeu!!


GOSTEI 0
Osocram

Osocram

23/01/2004

Oiii

Bom eu acho q o tempo vai de acordo c a prioridade...


GOSTEI 0
Icheuk

Icheuk

23/01/2004

Legal Cicero, fico muito feliz de saber que este topico esteja de ajudando, eu tambem estou desenvolvendo uma aplicacao aqui na empresa que usa thread, desta forma estou aprendendo tambem, e esta é a ideia deste topico vamos aprender todos juntos, pois assim fica muito mais e juntos podemos nos ajudar.

Vamos a sua pergunta.

Bom pelo que sei sobre sistema operacional, quem define o tempo de processamento de cada bloco é o SO, (lembra alguns assuntos acima no qual falei sobre dividir o pacote a ser processado em pedacinhos e cada pedacinho é processado e passa para o proximo da fila e assim por diante), bem o tempo que cada pedacinho fica no processador quem define é o SO e esta informação eu nao tenho, talvez com alguma pesquisa sobre os processos e como o windows trata a informação possa esclarecer ista duvida, porem vai variar de versao de windows ou seja o 95 trabalha diferentemente do 2000 ou xp.

Sendo assim o que conseguimos concluir, que ao utilizar a propriedade da prioridade da thread apenas conseguimos dar previlegios a ela mas o tempo de processamento vai ser o mesmo.

Quando

Bom Galera,

Adorei este tópico, pois naum tinha nem idéia de q isto poderia ser feito e a prova de que gostei muito é q decidi implementá-la nas minhas aplicações. Porém gostaria de tirar uma dúvida com relação ao tempo em que cada thread vai ter do precessador .. é possível determiná-lo .. ou este tempo varia de acordo com a prioridade ??

Cicero espero ter ajudado, e espero ter esclarecido um pouco a sua duvida, caso alguem tenha alguma coisa a acrescentar seria bem bacana.

E conto com a sua participação, coloque qualquer duvida ou qualquer dica que tenha descoberto, na implementação do seu sistema.

ICheuk


GOSTEI 0
Icheuk

Icheuk

23/01/2004

Valeu, osocram

E isso ai, a prioridade apenas permite que o processo frequente mais vezes o processador, e em cada vez que este processo frequentar o processador o tempo de vizita sera o mesmo de outro processo que tiver uma prioridade menor porem este ultimo processo ira frequentar o processador menas vezes.

ICheuk

Ps. e os seus projetos como andam ?


GOSTEI 0
Ltres

Ltres

23/01/2004

Ótimo... Simplesmente ótimo este topico, para quem naum sabia nada de thread eu to entendendo bem.

Mas como a ideia aqui é postar duvidas ai vai as minhas:

-Para fazer com q dois processo frequente ao mesmo tempo o processador eu tenho q declara-los em thread diferentes? Ou colocar um dentro e outro fora da thread?

-É possivel interromper um thread por uma procedure normal fora da thread?

Bom essas é as duvidas q tenho agora.. Assim q tiver mais tempo vou postar mais coisas aqui no forum.


GOSTEI 0
Emilio.cini

Emilio.cini

23/01/2004

vc pode usar TerminateThread pra finalizar unanthread, SuspendThread para pausar uma thread e ResumeThread para reiniciala, vc tbm nao precisa obrigatoriamente criar uma classe para usar threads, vc pode usar a api CreateThread para criar uma trhead e passar uma funcao no parametro, que sera excutada.
Voce pode utilizar tbm o SetThreadPriority pra setar a prioridade da thread, voce passa a ela o handle da thread e a prioridade, que estao divididas em:

PriorityMeaning
THREAD_PRIORITY_ABOVE_NORMALIndicates 1 point above normal priority for the priority class.
THREAD_PRIORITY_BELOW_NORMALIndicates 1 point below normal priority for the priority class.
THREAD_PRIORITY_HIGHESTIndicates 2 points above normal priority for the priority class.
THREAD_PRIORITY_IDLEIndicates a base priority level of 1 for IDLE_PRIORITY_CLASS, NORMAL_PRIORITY_CLASS, or HIGH_PRIORITY_CLASS processes, and a base priority level of 16 for REALTIME_PRIORITY_CLASS processes.
THREAD_PRIORITY_LOWESTIndicates 2 points below normal priority for the priority class.
THREAD_PRIORITY_NORMALIndicates normal priority for the priority class.
THREAD_PRIORITY_TIME_CRITICALIndicates a base priority level of 15 for IDLE_PRIORITY_CLASS, NORMAL_PRIORITY_CLASS, or HIGH_PRIORITY_CLASS processes, and a base priority level of 31 for REALTIME_PRIORITY_CLASS processes.


GOSTEI 0
Emilio.cini

Emilio.cini

23/01/2004

eu uso threads direto no meu sistema de lan house, elas melhoram em muito a performance.


GOSTEI 0
Ltres

Ltres

23/01/2004

Boa emilio.cini! Mas, pedindo um pouco mais, vc tem um exemplo pra nos de como criar usar o CreateThread?


GOSTEI 0
Icheuk

Icheuk

23/01/2004

LTres:

LTres como havia dito nas mensagens passados nao tem como frequentar ao mesmo tempo o processador, veja neste mesmo topico as mensagens passadas que vai entender, o que acontece é que temos a impressao que esta rodando ao mesmo tempo mas cada processo é quebrado em varias partes e cada parte roda um determinado tempo no processador (mas uma de cada vez) para poder realmente rodar mais de uma por vez temos que ter mais de um processador, veja nos assuntos passados e qualquer duvida pergunte, ok.

O seu sistema ja é um processo, quando inicia uma thread este passou a ter 2 processos ( isto sem contar os processos do windows e outros aplicativos que estao rodando neste momento na maquina), quando iniciamos a 2 thread temos 3 processos, sendo assim cada processo deve ser colocado dentro de uma nova thread pois se nao voce nao tem outro processo e sim parte do mesmo processo.

Sim é possivel interromper uma thread através de comandos pelo seu sistema (principal), ou até por outra thread.
Esta é uma questao que estou pesquisando neste momento pois estou precisando implementar isto no sistema.

E legal que tenha aprendido, pois parece ser algo bem complicado, mas na realidade apenas falta informação e exemplos sobre o assunto.

Continuo contando com a ajuda de todos.

ICheuk


GOSTEI 0
Icheuk

Icheuk

23/01/2004

Fala emilio.cini, tudo bem, legal pela ajuda, vai aqui uma duvida minha, como voce esta trabalhando com thread talvez ja tenha resolvido o problema.

Qual a melhor maneira que abortar uma thread mesmo ou seja limpar todo e qualquer residuo do processo da memoria.

Pois tentei com o terminate, nil, e de todas as formas acada gerando excessoes.

Qual o metodo que voce usa para fechar uma thread que ainda nao terminou, simplesmente para aborta-la.

Valeu pela ajuda, e por postar dicas aqui neste topico.

ICheuk


GOSTEI 0
Osocram

Osocram

23/01/2004

Ola, pessoal..

Cheuk naum pude mexer nas threads no fds... mas vou mexer acho q hj anoite....

Mas eu fiz um prog d agenda p anotar nomes, tel e talz.. sem BD... e na hora d fazer backup essas coisas vou tentar usar thread... so p naum travar o usuario...


Qq duvida ou descoberta postarei aqui..


GOSTEI 0
Icheuk

Icheuk

23/01/2004

Bacana, osocram, se caso fosse com BD voce teria que tomar o cuidado para o banco de dados estar fechado no momento do backup, mas como nao é o seu caso, deve funcionar, qualquer duvida estamos ai.

ICheuk


GOSTEI 0
Pedro Bugim

Pedro Bugim

23/01/2004

Fala Galera!
Acabei de ler as mens. deste tópico e achei muitíssimo interessante. Tive pouco contato com threads até hj e acabei de perceber que vou precisar muito disto... estou desenvolvendo um sistema aonde o usuário pode realizar um backup do banco de dados ou migrar tabelas paradox para interbase e vice-versa.
O problema é que estas tabelas são enormes, travando o sistema por mais de dois minutos nestas operações... Como já foi citado antes, cansei de ver funcionários indo tomar café ao realizar backup...
Rodei o exemplo dado no início do debate e funcionou perfeitamente. Com isso, comecei a persquisar um pouco e pretendo, em breve, já poder contar com este artifício em meus pgmas. Porém ainda continuo com uma enorme dúvida: como é que faço para dar prioridade maior ou menor para procedimentos distintos?! Se alguém souber, ficarei muito agradecido!
Abraços


GOSTEI 0
Icheuk

Icheuk

23/01/2004

Tudo bem, conforme a sua duvida, ao criar a thread voce atribui a prioridade dela dentro da lista de tarefas.

Ex.

thd := TMinhaThread.Create( True );
thd.Priority := tpLower;


Lembrando que thd é do tipo thread que voce definiu no sistema.

Continue pesquisando e mande as duvidas ou as pesquisas que conseguir fazer.

ICheuk


GOSTEI 0
Osocram

Osocram

23/01/2004

Este codigo eh p fazer a contagem d 1 a 3000 num label e d 1 a 6000 em outro label.

Observem q as 2 Classe d threads foram declaradas no proprio form1, e cq cada thread tem um procedimento ´Mostrar´.

unit Unit1; interface uses Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls; type T1 = class(TThread) private I:integer; procedure Mostra; protected procedure Execute; override; end; { of class declaration } type T2 = class(TThread) private I:integer; procedure Execute; override; procedure Mostra; end; { of class declaration } type TForm1 = class(TForm) Button1: TButton; Label1: TLabel; Label2: TLabel; procedure Button1Click(Sender: TObject); private { Private declarations } public { Public declarations } end; { of class declaration } var Form1: TForm1; implementation {$R *.DFM} procedure T1.Mostra; begin Form1.Label1.Caption:=IntToStr(I); end; procedure T1.Execute; var LI:integer; begin for LI:=1 to 3000 do begin I:=LI; Synchronize(Mostra); end; end; { of procedure } procedure T2.Mostra; begin Form1.Label2.Caption:=IntToStr(I); end; procedure T2.Execute; var LI:integer; begin for LI:=1 to 6000 do begin I:=LI; Synchronize(Mostra); end; end; { of procedure } procedure TForm1.Button1Click(Sender: TObject); begin T1.Create(false); T2.Create(false); end; { of procedure } end. { of Unit }



GOSTEI 0
Emilio.cini

Emilio.cini

23/01/2004

O metodo que utilizo é TerminateThread, mais vc pode utilizar CloseHandle tbm

function UnserThread(Parametro: Pointer): LongInt; stdcall;
begin
MessageBox(0, ´Teste´, ´Aviso´, 0);
Result:=0;
end;

var
ThreadID: DWORD;
ThreadHandle: THandle;

ThreadHandle:=CreateThread(nil, 0, TFNThreadStartRoutine(@UnserThread), nil, 0, ThreadID);

if ThreadHandle<>0 then CloseHandle(ThreadHandle);


GOSTEI 0
Icheuk

Icheuk

23/01/2004

Fala osocram, tudo bem.

Bem legal este seu exemplo, pois isto mostra que nao precisamos ter uma unit de Thread especifica para poder funcionar thread, porem a forma de se criar uma thread pode ser legal para documentação pois voce passa a ter uma unit(se é que pode ser dito desta maneira) com todas as fuções e procedures de sua thread dentro de um só lugar(tudo centralizado), acredito eu que desta forma pode ser melhor para documentar e fazer manutenção, e desta forma que voce apresentou se a sua unit for muito grande (ou seja com muitas funções e procedures) talvez seja um pouco trabalhoso para se dar manutenção, mas de qualquer forma um grande exemplo, pois mostra como criar a thread através de programação, valeu, bem legal mesmo.

ICheuk

Ps. Continue postando coisas


GOSTEI 0
Icheuk

Icheuk

23/01/2004

emilio, tudo bem com voce.

Bom, achei bem legal o seu exemplo, infelizmente nao tive tempo para testar pois hoje estou numa correria so, pois tenho uma tarefa para entregar ate o final de semana e esta uma grande correria, mas so de olhar achei bem interessante, so me responda uma coisa caso eu esteja em um loop infinito (este loop esta dentro da minha thread, e fica verificando uma tabela do banco de dados entao esta thread so fecha quando eu quizer ou se fechar o sistema), caso esta situacao aconteça este seu metodo ira destruir a thread ou vai ficar travada devido ao loop infinito, pois com o metodo Terminate ela fica preza pois o loop é infinito.

ICheuk

Ps. Emilio, e obrigado pela ajuda e colaboração neste topico.


GOSTEI 0
Icheuk

Icheuk

23/01/2004

Emilio tudo bem,

Bom fiz alguns testes e consegui efetuar com o seguinte codigo, de uma olhada e me diga se é isto ou voce faz de outra forma.

if assigned(wMinhaThread) Then
begin
wMinhaThread.Terminate;
if wMinhaThread.Suspended then wMinhaThread.Resume;
wMinhaThread.WaitFor;
wMinhaThread.Free;
wMinhaThread := nil;
end;


ICheuk


GOSTEI 0
Nildo

Nildo

23/01/2004

Olá!

Bom... Tenho algumas observações a fazer sobre Thread:

Eu me interesso muito por Threads, controle de processos, esse tipo de coisa. Tanto é que baseado nisso eu fiz uma rotininha que me possibilita Hookar APIs tais como: SEND e RECV do WinSock (programa do tipo sniffer).
Tenho algumas observações: Dentro de uma thread, pelo a mor de deus, NÃO USEM VCL DENTRO DE UM EXECUTE DE UMA THREAD. Ps. ShowMessage é VCL, usem o MessageBox. Se possível escreva um Message Handler (capturador de mensagens do tipo: WM_COPYDATA ou WM_QUALQUER COISA) na propria Thread.

E Ivan (Olá!) para parar uma Thread você pode usar o SUSPEND (RESUME para continuar novamente) ou o TERMINATE para destruir a thread. Ela para de fazer o que ela estiver fazendo e fecha a thread. Mesmo se estiver em um Loop infinito. Mas lembre-se: Se ela estiver em Loop Infinito ela não vai influenciar na execução de sua thread principal (Caso não saiba, tudo no windows eh executado via Thread: Janelas, processos, mensagens, etc), mas sim no Windows Inteiro. Pode deixar todo seu computador Lento.
É isso que tenho a advertir sobre as threads. Bom, estou deixando este tópico como fixo (a pedido do autor Ivan) pois é um tópico interessante


GOSTEI 0
Belo

Belo

23/01/2004

O Guinther Pauli, um dos editores do ClubDelphi ganhou no ano passado um concurso na Borland onde ele desenvolveu um programa sobre Threads que é muito bom e vale dar uma olhada, pois praticamente tem tudo. Segue o link:

http://codecentral.borland.com/codecentral/ccweb.exe/download?id=17644


GOSTEI 0
Kroki

Kroki

23/01/2004

A respeito do Topico Syncronize,a Borland aconselha nao usar Syncronize em projetos VCL,evintando Loopings e erros.


GOSTEI 0
Beppe

Beppe

23/01/2004

A respeito do Topico Syncronize,a Borland aconselha nao usar Syncronize em projetos VCL,evintando Loopings e erros.

:?:


GOSTEI 0
Icheuk

Icheuk

23/01/2004

Ola a todos, desculpe o meu afastamento momentaneo, pois estou com muitas tarefas, mas vamos la, este final de semana eu encontrei um material muito bom sobre thread e vou estuda-lo e em seguida postarei as dicas e o resultado aqui, ok.

Legal pois percebi que o numero de pessoas discutindo o topico esta crescendo e com isso acredito eu o numero de informacoes sobre thread deve aumentar e desta forma acho que vai colaborar para que todos possam ter um conhecimento maior sobre o assunto.

Belo

Belo eu tentei o link que voce passou e aparece um erro falando que nao achou a pagina, por favor de uma olhada no link e confirme pois o exemplo deve ser muito bom, pois o autor é indiscutivel.

Beppe

Concordo com voce nao entendi o que o Kroki quis dizer com syncronized nao poder ser usado com aplicacao VCL pois na realidade pelo que aprendi o syncronized é o metodo para se atualizar componentes visuais da aplicacao ou seja VCL.

Kroki

podemos discutir o tema melhor, voce poderia passar maior informacao disto que disse.

E agradeço a todos os outros participantes que apenas leram o topico, e se cadastrem no clubedelphi e participem do topico perguntando ou colocando informacoes pois desta forma todos poderam aprender sobre thread, pois as informacoes sobre este tema é muito pouca e sem divulgacao.


GOSTEI 0
Belo

Belo

23/01/2004

O link que eu passei só fica disponível quem é cadastrado no site CodeCentral da Borland. De qualquer forma deixarei disponível no meu servidor até sexta, ai vai o link:

http://eduardo-belo.sites.uol.com.br/delphi/threadguinther.zip


Belo Belo eu tentei o link que voce passou e aparece um erro falando que nao achou a pagina, por favor de uma olhada no link e confirme pois o exemplo deve ser muito bom, pois o autor é indiscutivel.


[color=red:7450b0df66][b:7450b0df66]Nota do moderador(Beppe): É conveniente citar apenas a parte relevante do tópico.[/b:7450b0df66][/color:7450b0df66]


GOSTEI 0
Beppe

Beppe

23/01/2004

O método Synchronize é a maneira de se realizar um [i:3ed7340f6d]rendezvous[/i:3ed7340f6d]* no Delphi. Como o loop da VCL que processa as mensagens está no thread principal, deve haver uma maneira dos threads modificarem de modo consistente dados no espaço de outro, sem que nada seja sobrescrito indevidamente.

Há um tempo atrás tinha feito um exemplo usando Synch, disponibilizo pra download [url=http://www.afw.hpg.com.br/Turtle.tar.gz]aqui[/url].

* Ponto de encontro na execução de dois threads, onde apenas um deles pode executar, o outro espera o término do rendezvous.


GOSTEI 0
Kroki

Kroki

23/01/2004

Li a respeito no Help do Delphi.
Testei um Chat em CLX que usa o Sinchronize.
Quando o fluxo do Chat era grande (+-15 se comunicando)alguns do chat nao recebiam a mensagem.
Entao nao descobri oque era e comecei a vasculhar o Help do Delphi e achei (vou procurar pra postar o Help)uma nota aconselhando em Aplicacoes VCL,(esqueci de dizer que transportei o codigo para VCL),era desnecessario o Sinchronize pis poderia deixar a aplicacao em Looping porque esse metodo era para gerar um sincronismo em aplicacoes CLX.
Retirei e resolvi 90¬ dos meu problemas.
Lendo um topico aqui,(que estava travado),e um usuario fez o mesmo e resolveu os erros do seu programa.
Foi por isso que comentei o assunto para saber mais.
Enquanto estava escrevendo achei o Help:
Help\Delphi\thread functions:Execute Method\
´...
Note

Because Synchronize uses the message loop, it does not work in console applications. You must use other mechanisms, such as critical sections, to protect access to VCL or CLX objects in console applications.

You do not always need to use the main thread. Some objects are thread-aware. Omitting the use of the Synchronize method when you know an object´s methods are thread-safe will improve performance because you don´t need to wait for the VCL or CLX thread to enter its message loop. You do not need to use the Synchronize method for the following objects:

Data access components are thread-safe as follows: For BDE-enabled datasets, each thread must have its own database session component. The one exception to this is when you are using Microsoft Access drivers, which are built using a Microsoft library that is not thread-safe. For dbExpress, as long as the vendor client library is thread-safe, the dbExpress components will be thread-safe. ADO and InterBaseExpress components are thread-safe.
When using data access components, you must still wrap all calls that involve data-aware controls in the Synchronize method. Thus, for example, you need to synchronize calls that link a data control to a dataset by setting the DataSet property of the data source object, but you don´t need to synchronize to access the data in a field of the dataset.

For more information about using database sessions with threads in BDE-enabled applications, see Managing multiple sessions.
Controls are not thread-safe.
Graphics objects are thread-safe. You do not need to use the main VCL or CLX thread to access TFont, TPen, TBrush, TBitmap, TMetafile (VCL only), TDrawing (CLX only), or TIcon. Canvas objects can be used outside the Synchronize method by locking them.

While list objects are not thread-safe, you can use a thread-safe version, TThreadList, instead of TList.

Call the CheckSynchronize routine periodically within the main thread of your application so that background threads can synchronize their execution with the main thread. The best place to call CheckSynchronize is when the application is idle (for example, from an OnIdle event handler). This ensures that it is safe to make method calls in the background thread...
´


GOSTEI 0
@line

@line

23/01/2004

Oi Pessoal!

Peço lincença para entrar no fórum. Tenho mUitas dúvidas sobre thread, li várias coisas na net, mas parece que quanto mais eu leio, mais me confundo. Eu sei qual é idéia de thread, porém não consigo criar!
Pequei uma thread + ou - pronta, ela tem um contrutor e 2 procedures: 1 salva dados e outra incrementa o progressbar. No contrutor há as seguintes linhas:

Constructor TSalva.Cria;
begin
inherited Create(True);
FreeOnTerminate := true;
Priority :TpLower;
Resume;
end;

O que acontece é que não consigo fazer com que a thread termine!

Ps: se vcs souberem onde tem material a respeito,indiquem-me o site por favor.

Muito obrigada pela ajuda,
Aline.


GOSTEI 0
Icheuk

Icheuk

23/01/2004

Ola @line, tudo bem, espero que sim, vamos la.

Voce deve estar usando um exemplo para ver as funcionalidades, por um acaso voce leu todas as outras mensagens postadas, pois acho que tira muitas duvidas sobre conceito de thread, e tem exemplos legais tambem, que acredito eu consegue desta forma iniciar em threads.

Porem com relacao a sua duvida sobre terminar a thread:

voce pode usar o MinhaThread.Terminate;

Isto faz com que a sua thread termine, porem caso esteja em um while (loop) e este loop nao tenha terminado. voce pode colocar como condicao do while a seguinte condicao para realmente terminar o while de maneira correta e assim permitir com que a thread termine.

While (sua condicao normal) and Terminated = False do

Ou seja, seu while vai fazer enquanto sua condicao prevalecer e voce nao tiver tomado a decisao de ter terminado a thread.

Espero ter esclarecido sua duvida, e me desculpe pela demora da resposta pois ando meio ocupado e nao estou conseguindo responder a todas as mensagens.

E qualquer outra duvida é so postar.


GOSTEI 0
@line

@line

23/01/2004

ICheck

Isso quer dizer que, se eu quero permitir ao usuario terminar uma contagem muito longa feita por uma thread eu posso colocar: MinhaThread.terminate dentro de um botão?

Obrigada,
Aline.


GOSTEI 0
Icheuk

Icheuk

23/01/2004

Sim @line, resolve porem como disse anteriormente voce deve usar dentro da sua thread em uma condicao para parar a contagem o terminated.


GOSTEI 0
Icheuk

Icheuk

23/01/2004

Ola pessoal, eu andei pesquisando e descobri que na revista clubedelphi numero 21 que fala sobre XML tem uma materia muito boa sobre thread e gerenciamento de thread.

Vale a pena dar uma olhada.


GOSTEI 0
Icheuk

Icheuk

23/01/2004

E ai pessoal como vao as coisas, e os projetos em threads, ninguem tem mais duvidas, vamos postar mais.

Bom comecei a ler o artigo da revista mencionada acima e tem um programinha de controles de threads muito legal e segue abaixo o link para baixar os arquivos sitados na materia.

http://www.clubedelphi.com.br/edicao21/multithreading.zip

Por favor olhem e comentem.

lembranças a todos.


GOSTEI 0
Osocram

Osocram

23/01/2004

Ae...
voltei ao forum
hehe mto tempo sumido... mto trampo por aqui..
Seguinte...

Tava testanto as thread... mas ainda naum consegui entender mto bem as coisas.

o prog q estou faze eh o seguinte...
coloquei um PanelPrincipal,e uns Panel pequenos... enfileirados um ebaixo do outro (4 panels) dae qdo iniciace eu gostaria de poder fazer eles irem andando.
Ateh ae facil, neh?

Mas eu queria poder mudar a velocidade deles em tempo d execucao....

constructor TThreadMover.Criar(PanelC: TPanel;Intervalo:integer); begin Create(False); Panel := PanelC; G_Intervalo := Intervalo; FreeOnTerminate := True; end; procedure TThreadMover.Incrementa; begin panel.left := panel.left-G_Intervalo; end; { TThreadMover } procedure TThreadMover.Execute; begin // while panel.Left > 0 do if panel.Left > 0 then Synchronize(Incrementa); { Place thread code here } end;


como devo proceder?
Estou fazendo varios teste p ver qual fica melhor....

Oq eu quero fazer eh bem mais complexo q isso... se naum entender nada do q falei ateh agora.. me avise dae explico melhor.

OBS: ICheuk vou ver o ex. q vc mandou ae


GOSTEI 0
Beppe

Beppe

23/01/2004

Se quem manda mudar G_Intervalo está no thread principal(VCL), vc naum usa Syncronize. Mas ainda é preciso proteger contra acesso simultâneo, tanto na leitura como na escrita de G_Intervalo. Pode usar TCriticalSection ou TMultiReadExclusiveWriteSynchronizer(ufa).


GOSTEI 0
Beppe

Beppe

23/01/2004

Ah, como o que quer fazer é uma operação simples, pode usar InterlockedExchange.

InterlockedExchange(Seu_Thread.G_Intervalo, Novo_Intervalo);



GOSTEI 0
Prgdelphi

Prgdelphi

23/01/2004

Pessoal, li no fórum todas as mensagens a respeito de threads e já aprendi muita coisa... Estou com um problema em um sistema que desenvolvi que possui 4 threads rodando ao mesmo tempo.

Uma delas, a mais pesada e a que dá mais problema, está me deixando de cabelo branco já... vou explicar mais ou menos como ela funciona, e se alguém puder me dar umas dicas de como trabalhar para evitar erros, ficaria muito grato.

Esta thread não fica na memória o tempo todo que o programa está no ar. Mas quando ela precisa ser executada, dependendo, fica um bom tempo rodando em paralelo.

Junto com ela, crio um form para informar o usuário o andamento do processamento. Crio também, no form principal do programa um Gauge, que vai incrementando. Os processos de atualização do Form e incremento do Gauge chamo usando o synchronize.

A thread trabalha com banco de dados, que segundo o fabricante é Thread-Safe e multi-usuario. Trabalha também com ADOconnection, ADOTable e TDataset. Crio todos os componentes na criação da thread.

Carrego também uma DLL que é usada para checagem de alguns dados que estão sendo processados. O processamento dela é bem pesado e às vezes bem demorado.

Vários problemas ocorrem... algumas vezes ela trava o programa inteiro, congelando todas as telas, outras o programa simplesmente fecha, do nada, sem erro nem nada. Acontece também que depois de um bom tempo processando, ela começa a ficar um pouco mais lenta...

Um outro ponto crítico que acho que existe nela também é que ela pega um determinado arquivo JPEG, transforma em BMP e grava no disco, para em seguida ser aberto novamente este arquivo. Isto porque a função só permite que se abra um arquivo do disco.

Acredito que o que está acontecendo aí são alguns problemas com sincronização. Alguém poderia dar alguma informação em qual a melhor maneira de se fazer?

Obrigado.


GOSTEI 0
Beppe

Beppe

23/01/2004

Cara, eu não acredito que ADO seja thread-safe, ao menos não por default. Pra começar a resolver seu problema, posso sugerir criar uma conexão para cada thread, além da conexão principal.


GOSTEI 0
Prgdelphi

Prgdelphi

23/01/2004

Exatamente... Eu também não tenho certeza se ADO é thread-safe ou não... estou fazendo do jeito que você falou.. Em cada thread eu crio uma conexão com o banco. Mas acredito que o ADO não esteja sendo o problema principal, pois sempre quando dá pau no programa, ele ja passou do ponto onde usava conexão ADO.

Valew.


GOSTEI 0
Marcosrocha

Marcosrocha

23/01/2004

Eu não manjo de Thread, mas se existe alguém que manja é o professor da Escola Técnica Federal de Palmas - Manoel Campos...
Vale a pena baixar e ´tentar´ estudar... :wink:
[url]http://www.delphibr.com.br/baixar.php?tipo=1&id=99[/url]


GOSTEI 0
Dart

Dart

23/01/2004

Ola

Sempre quiz saber sobre Thread mas numca tive tempo de estudar nem usar devido a meus sistemas serem pequenos. Mas para melhorar a qualidade deles e tirar eles da escuridao, vou estudar + sobre Thread.
E esse topico me ajudou muito, e pretendo usar, pra começar em meus relatorios. Deu trabalho ler as menssagens mas vlw muito o tempo q gastei.


Espero logo postar as minhas dividas...

Opa tenho uma...
So funciona em VCL?

Grato


GOSTEI 0
Nildo

Nildo

23/01/2004

Opa tenho uma... So funciona em VCL? Grato


Se você usar pela classe TThread, sim. Mas dá para usar em aplicativos não VCL, usando a API CreateThread, do Windows. Mas dentro dela você tem que tomar muito cuidado por ser ThreadSafe, não pode usar VCL dentro dela.

Um abraço!


GOSTEI 0
Marcosrocha

Marcosrocha

23/01/2004

Falando sobre o assunto, (desculpem se isso já tá postado no tópico) mas eu queria saber quais os tipos de Thread q eu posso criar e suas Aplicações/Recomendações/Propriedades particulares...


GOSTEI 0
Nildo

Nildo

23/01/2004

Falando sobre o assunto, (desculpem se isso já tá postado no tópico) mas eu queria saber quais os tipos de Thread q eu posso criar e suas Aplicações/Recomendações/Propriedades particulares...


Não existe tipo de thread. Uma thread é um bloco de código que será executado em paralelo a sua aplicação. Isso é, enquanto uma thread está sendo executada, você pode ter N outras threads sendo executadas, sem uma interferir no processamento da outra (o que pode alterar é a velocidade de processamento, no caso definida na Prioridade).

É recomendável quando se quer fazer algum processo pesado em background. O usuário nem vai notar que o processo está sendo executado, e continuará podendo usar o sistema normalmente


GOSTEI 0
Marcosrocha

Marcosrocha

23/01/2004

Não existe tipo de thread. Uma thread é um bloco de código que será executado em paralelo a sua aplicação.

É que eu tinha ouvido falar que existem Threads independentes, Threads que podem ser ´dependentes´ da aplicação ou coisa assim...
Acredito que se eu quisesse fazer uma Thread dependente da minha aplicação era só implementar nela uma rotina que verificasse a existência do sistema, se ela não o encontrasse ela automaticamente terminaria.
Por isso veio a dúvida! :oops:
Mas até hoje eu não tive coragem (nem tempo) para criar e testar uma Thread pra ver se eu aprendi!! 8)


GOSTEI 0
Nildo

Nildo

23/01/2004

É que eu tinha ouvido falar que existem Threads independentes, Threads que podem ser ´dependentes´ da aplicação ou coisa assim... Acredito que se eu quisesse fazer uma Thread dependente da minha aplicação era só implementar nela uma rotina que verificasse a existência do sistema, se ela não o encontrasse ela automaticamente terminaria. Por isso veio a dúvida! :oops: Mas até hoje eu não tive coragem (nem tempo) para criar e testar uma Thread pra ver se eu aprendi!! 8)


Toda thread que for criada (pelo menos no ambiente Windows), vai pertencer ao processo que a criou. Não há como criar uma thread independente de processo. Tanto é que alguns vírus, quando querem se camuflar, criam threads no contexto do processo do Explorer.exe, para que alguns Anti-virus pensem que o código malicioso é um código amigo (executado pelo explorer). Conhecendo a estrutura interna de gerenciamento do Windows, vai perceber que as Threads estão ligadas aos processos, logo, para existir uma Thread é necessário de um processo para alojar a mesma. Ela sempre vai ser executada dentro da área de memória alocada de um determinado aplicativo (logo ela pertence aquele aplicativo)


GOSTEI 0
George_piaulino

George_piaulino

23/01/2004

Gostei muito deste tópico, pois já trabalho a muito tempo com threads e quero dar uma dica bem legal que é Array de threads.

Vamos citar um exemplo que vc precise fazer leitura serial de 3 coms.

Crie um form com um checkbox e um button

Crie uma thread com nome da classe de thLerSerial

O código das units estão abaixo

unit 1 //

antes declare a unit2 na unit 1.

+++++++++++++++++++++++++++++++++++++++++++++++

var
Form1: TForm1;
lerserial:array[0..2] of ThLerSerial;

implementation

{$R *.dfm}

procedure TForm1.Button1Click(Sender: TObject);
var
i:integer;
begin
Button1.Enabled:=false;
for i:=0 to 2 do
begin
lerserial[i]:=ThLerSerial.Create(true);
lerserial[i].scom:=pchar(´COM´+inttostr(i));
end;

end;

procedure TForm1.CheckBox1Click(Sender: TObject);
var
i:integer;
begin
if CheckBox1.Checked then
for i:= 0 to 2 do
lerserial[i].Resume;
end;

procedure TForm1.FormCreate(Sender: TObject);
var
i:integer;
begin
if CheckBox1.Checked then
for i:= 0 to 2 do
lerserial[i].Terminate;
end;



++++++++++++++++++++++++++++++++++++++++++++++

unit da thread

Unit2;

interface

uses
Classes, windows;

type
ThLerSerial = class(TThread)
scom:Pchar;
private
{ Private declarations }
protected
procedure Execute; override;
end;

implementation
uses unit1;

{ ThLerSerial }

procedure ThLerSerial.Execute;
begin
FreeOnTerminate:=true;
while not terminated do
begin
sleep(200);
//rotina de leitura de serial, insira aqui o código, procedure, função, classe, objeto, dll de leitura
if not Form1.CheckBox1.Checked then
Suspend;
end;
{ Place thread code here }
end;

//dica : sempre tente desmembrar o código em várias units, para serem usadas pela thread
//sempre faça uso do Synchronize() para manipular form e os componentes que por ele é utilizado,
//caso contrario utilize procedures, functions e units.
//sempre utilize o sleep, pois ele alivia a memória.
//sempre termine a thread antes de fechar o FORM
end.


+++++++++++++++++++++++++++++++++++++++++++++++

Este é um pequeno exemplo de uso de array de thread e com certeza vc pode utilizar para vários outros tipos de classes.

Bom, divirtam-se...

Abraços

George


GOSTEI 0
Nildo

Nildo

23/01/2004

Mais uma coisa importante que todos devem levar em consideração ao utilizarem Threads:

Como o amigo Piaulino disse, faz bem o uso do Synchronize() para manipular objetos da VCL. Alias, não faz bem, faz-se necessário. Vou começar exemplificando um erro que uma thread que manipula objetos pode causar:

Vamos supor que você tenha uma Thread que fica alterando o valor de um Caption de algum objeto, constantemente. Quando você for alterar esse valor desse objeto, fora dessa thread, pode ocasionar um erro pois a Thread estará alterando a memória da String do caption, no momento que você também for tentar alterar. Então serão duas thread diferentes tentando alterar o mesmo local no mesmo instante (2 threads: A do seu form, e a que citei acima).

O Synchronize() existe para evitar que isso aconteça, o Synchronize vai executar uma procedure, no contexto do seu form principal. Ao chamar o Synchronize, somente para atribuir o novo valor ao objeto, a thread principal da sua aplicação (no caso, a thread do form principal) vai parar de fazer o que estava fazendo, só para executar a procedure que você passou como parametro ao Synchronize(), no contexto dele mesmo. Então torna-se impossível o Form principal e a Thread tentarem alterar o valor ao mesmo tempo.

Qualquer coisa estamos aí :D


GOSTEI 0
Marcosrocha

Marcosrocha

23/01/2004

Gostei muito deste tópico, pois já trabalho a muito tempo...

Até hoje tentei criar e trabalhar com Thread mas em todos os exemplos que vi (inclusive o do Delphi) eu não consegui entender...
Será q vc não teria um exemplo bem fácil/legal pra eu entender?? (sem ser complicado como o desse array de threads??)


GOSTEI 0
George_piaulino

George_piaulino

23/01/2004

[quote=´mcblade´][quote=´piaulino´]Gostei muito deste tópico, pois já trabalho a muito tempo...

Até hoje tentei criar e trabalhar com Thread mas em todos os exemplos que vi (inclusive o do Delphi) eu não consegui entender...
Será q vc não teria um exemplo bem fácil/legal pra eu entender?? (sem ser complicado como o desse array de threads??)



Para começar vamos entender a primeira vantagem de uso de uma trhead.


Passo 1.

Crie um projeto e coloque no form (unit1) duas gauges e 2 dois labels e um timer seguintes parametros:

Label1.caption:=´Exemplo com Timer´

Abaixo deste label coloque o gauge1

Label2caption:=´Exemplo com Thread´
Abaixo deste label coloque o gauge2

Button1.enabled:=false;
Button1.caption:=´Ativa´

escolha o tamanho, comprimento e largura que quiser para estes componentes acima

TImer1.enabled:=true;
Timer1.interval:=100;


Passo 2.

Crie uma thread(unit 2) com nome da classe thTeste e deixe o código desta maneira.(não copie mas sim escreva).

+++++++++++++++++++++++++++++++++++++++++++++++

unit Unit2;

interface

uses
Classes, windows;

type
Thteste = class(TThread)
private
{ Private declarations }
protected
procedure Execute; override;
procedure RefreshGauge;
end;

implementation
uses unit1;

{ Thteste }

procedure Thteste.Execute;
begin
FreeOnTerminate:=true;
while not terminated do
begin
Synchronize(RefreshGauge);
if Form1.Gauge2.Progress = 100 then
Suspend;
sleep(100); //observe que é o mesmo tempo do timer
end;

end;

procedure Thteste.RefreshGauge;
begin
with Form1 do
Gauge2.Progress:=Gauge2.Progress+1;
end;

end.

+++++++++++++++++++++++++++++++++++++++++++++++


Passo 3

declare na unit 1 a unit 2


Passo 4

Veja o código da unit1, não copie e sim faça.

var
Form1: TForm1;
teste:thteste;
implementation

{$R *.dfm}

procedure TForm1.Timer1Timer(Sender: TObject);
begin
Gauge1.Progress:=Gauge1.Progress+1;
if Gauge1.Progress = 100 then
begin
Timer1.Enabled:=false;
Button1.Enabled:=true;
end;
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
Gauge1.Progress:=0;
Gauge2.Progress:=0;
Button1.Enabled:=false;
Timer1.Enabled:=true;
teste.Resume;
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
teste:=Thteste.Create(false);
end;

++++++++++++++++++++++++++++++++++++++++++++


Agora eu vou perguntar....

Qual é a vantagem que a Maria levou neste caso...??? Descubra e verá.

Por favor poste aqui as vantagens e desvantagens e vamos discutir o assunto.

Na próxima irei fazer um projeto com tabela.


Abraços

George


GOSTEI 0
Marcosrocha

Marcosrocha

23/01/2004

Não sei se estou certo mas a Thread é mais rápida!!
Isso porque ela é executada na lista de processos do windows economizando memória, o timer utiliza a memória da aplicação, por isso é executado mais lentamente.


GOSTEI 0
Nildo

Nildo

23/01/2004

Não sei se estou certo mas a Thread é mais rápida!! Isso porque ela é executada na lista de processos do windows economizando memória, o timer utiliza a memória da aplicação, por isso é executado mais lentamente.


Não. Todo código da sua aplicação está executando em alguma thread. Seja ela a thread de um Form, ou não, sempre está numa thread. Então é sempre a mesma velocidade. Mas depende da Prioridade que você seta para uma thread, pode deixar as demais mais lentas.


GOSTEI 0
Beppe

Beppe

23/01/2004

mcblade, como vc chegou a esta conclusão? (que é sem fundamentos, mas estou curioso)


GOSTEI 0
Marcosrocha

Marcosrocha

23/01/2004

mcblade, como vc chegou a esta conclusão? (que é sem fundamentos, mas estou curioso)

É que nesse mesmo tópico, a alguns posts atrás, acho q o Nildo disse que a Thread se utiliza da memória ou coisa assim...
Toda thread que for criada (pelo menos no ambiente Windows), vai pertencer ao processo que a criou. Não há como criar uma thread independente de processo. Tanto é que alguns vírus, quando querem se camuflar, criam threads no contexto do processo do Explorer.exe, para que alguns Anti-virus pensem que o código malicioso é um código amigo (executado pelo explorer). Conhecendo a estrutura interna de gerenciamento do Windows, vai perceber que as Threads estão ligadas aos processos, logo, para existir uma Thread é necessário de um processo para alojar a mesma. Ela sempre vai ser executada dentro da área de memória alocada de um determinado aplicativo (logo ela pertence aquele aplicativo)

Então por isso eu pensei que fosse... :oops:


GOSTEI 0
Randallo

Randallo

23/01/2004

Colegas, como eu acesso as propriedades e métodos do objeto que criou a thread dentro da thread?

por exemplo:

constructor TClientSendThread.Create(CreateSuspended: Boolean);
begin
inherited Create(CreateSuspended);
FreeOnTerminate := true;
aTCPClient := TTCPClient.Create;
aTCPClient.LocalHost := aClientManager.LocalHost; //DELPHI NÃO ACEITA
end;

procedure TClientManager.GetServersStatus;
var
i: integer;
begin
for i:=0 to aServers.Count-1 do begin
TClientSendThread.Create(true);
end;
end;

No caso o objeto aClientManager que é uma instância do tipo TClientManager possui uma propriedade que é LocalHost, como faço para dentro da thread acessar essa propriedade do objeto que a criou?

E como eu acesso as threads criadas pelo objeto dentro do próprio objeto?

Obrigado.


GOSTEI 0
Deathcon4

Deathcon4

23/01/2004

Também já enfrentei este problema, estava testando um script bem simples para não perder o jeito. Quando tento executar o programa, ele congela. Mas programado através do console, o programa funciona corretamente.

Muito estranho. Não sei porque o registrador não é liberado, creio que seja no registrador que acumula os valores. Andei pesquisando sobre o assunto. é o registrador EAX ou por ter feito um loop infinito e o registrador fica sempre ocupado.

Po exemplo, no código abaixo, ele faz todos os cálculos corretamente mas não sai do loop.

procedure TForm1.Button1Click(Sender: TObject);
var idade, media, acm: real;
con : integer;
begin
acm := 0;
con := 0;
idade := strtoint(edit1.Text);
while idade <> -1 do
begin
acm := acm + idade;
idade := strtoint(edit1.Text);
con := con + 1;
end;
media := acm/con;
label1.Caption := floattostr(media);
edit1.Clear;
//sleep(1000);
end;


GOSTEI 0
George_piaulino

George_piaulino

23/01/2004

Thread eh show, sempre uso para minha aplicações


GOSTEI 0
Rengaf

Rengaf

23/01/2004

Iai pessoal

sou totalmente leigo no assunto threads, talves a minha pergunta até seja meio idiota ma estou na duvida.

Creio que daqui alguns anos será comum mauinas multiprocessadas, para que nossos aplicativos usem toda a capacidade dessas maquinas poderiamos usar threads???

:?


GOSTEI 0
Braytiner Heggendorn

Braytiner Heggendorn

23/01/2004

Estou com um pequeno problema: Iniciei o uso de Thread em minha aplicação, a fim de realizar um processo de transferência de dados em background. Faço um loop no banco de dados e o usuário continua fazendo suas ações, isso sem a aplicação travar, porém quando chamo um ApplyUpdates de um clientdataset (isso no código da Thread), minha aplicação trava. Há alguma forma de se evitar esse travamento?


GOSTEI 0
Rinez

Rinez

23/01/2004

Prezados colegas:
Como construir uma Thread para executar um select ao banco de dados Fireberd com Dbexpress ou zeos onde a cada 4 segundos executo esse select e sempre necessito ligar e desligar esse acesso. Atualmente faço com timer e gostaria de verificar a performa da mudança de timer para Thread? :?:


GOSTEI 0
Tremonti

Tremonti

23/01/2004

minha thread para quando abro uma Query


GOSTEI 0
Tiago Nunes

Tiago Nunes

23/01/2004

Tenho a thread abaixo e gostaria de alterar o Sleep do loop em tempo de execução, alguem sabe como fazer isso ?
Se alterar a variavel iSleepPrecoTarget em tempo de execuçção, da o erro "Out of System Resources".

Segue o codigo abaixo:

type
TVarrerOportunidadeTarget = class(TThread)
protected
procedure Execute; override;
end;

...

procedure TVarrerOportunidadeTarget.Execute;
begin
while True do
begin
Sleep(iSleepPrecoTarget);
if not(FPrincipal=nil) then
begin
DMAtendimento.VerificaOportunidadeTarget;
end;
end;
end;

procedure TDMAtendimento.ThreadTargetTimer(Sender: TObject);
var oTheadTarget: TVarrerOportunidadeTarget;
begin
Screen.Cursor := crHourGlass;
try
Application.ProcessMessages;
oTheadTarget := TVarrerOportunidadeTarget.Create(True);
oTheadTarget.FreeOnTerminate := True;
oTheadTarget.Resume;
finally
Screen.Cursor := crDefault;
end;
end;
GOSTEI 0
POSTAR