Você está na página 1de 4

17/06/13

Threads no Delphi, por onde comear ? Parte I | Diego Garcia

Diego Garcia
Delphi, Scrum, Arquitetura de Software e um pouco mais

Threads no Delphi, por onde comear ? Parte I


Publicado em 31/01/2013

Thread um termo conhecido por qualquer informata que se preze, mas para quem no se recorda, qualquer aplicao utiliza no minimo uma thread (a thread principal ou main thread) onde o fluxo do processamento executado, nessas aplicaes os comandos so executados um por vez de forma sequencial. At ai nada demais, mas a coisa passa a ficar interessante quando usamos mais de uma thread em uma aplicao, fazendo com que seja possvel executar processamentos de forma paralela. No dia a dia usamos as threads para gerenciar tarefas que precisam ser executadas paralelamente, melhorar desempenho de processamentos, etc. Mas no se iluda, usar threads simples, mas requer alguns cuidados. Deixando a teoria e o blablabla de lado, vamos ver um pouco sobre como funcionam as threads no Delphi. Comearemos criando um exemplo bem bsico, faremos um mtodo que escreve de 1 a N linhas em um arquivo de texto tendo o intervalo de 1 milissegundo a cada linha escrita, o nome deste arquivo sempre ser hora, minuto, segundo e milsimo de criao e o numero de linhas escritas, ex: 14-30-01200_total_linhas_1500.txt. Inicialmente criaremos esse mtodo da forma comum e depois passaremos para uma thread, assim conseguiremos realizar algumas comparaes no resultado final. Para a execuo comum, faremos dessa forma: 1 2 3 4 5 6 7 8 9 1 0 1 1 1 2 1 3 1 4 1 5 1 6 1 7 1 8

p r o c e d u r ee s c r e v e r A r q u i v o D e T e x t o ( c o n s td i r A r q u i v o :s t r i n g ; l i n h a s A I m p r i m i r :i n t e g e r ) ; v a r l i n h a s A r q u i v o T e x t o:T S t r i n g L i s t ; I :I n t e g e r ; b e g i n l i n h a s A r q u i v o T e x t o: =T S t r i n g L i s t . C r e a t e ; t r y f o rI: =1t ol i n h a s A I m p r i m i rd o b e g i n l i n h a s A r q u i v o T e x t o . A d d ( f o r m a t ( ' L i n h an u m e r o% d ' , [ i ] ) ) ; S l e e p ( 1 ) ; e n d ; l i n h a s A r q u i v o T e x t o . S a v e T o F i l e ( F o r m a t ( ' % s \ % s _ t o t a l _ l i n h a s _ % d . t x t ' , [ d i r A r q u i v o , F o r m a t D a t e T i m e f i n a l l y l i n h a s A r q u i v o T e x t o . F r e e ; e n d ; e n d ;

Para testar esse mtodo, faremos com que ele seja executado 3 vezes e analisaremos a diferena de tempo de gravao entre um e outro, lembrando que, como ainda no estamos trabalhando com threads, ser escrito um arquivo por vez. 1 2 3 e s c r e v e r A r q u i v o D e T e x t o ( E x t r a c t F i l e D i r ( P a r a m S t r ( 0 ) ) , 1 0 5 0 0 ) ; e s c r e v e r A r q u i v o D e T e x t o ( E x t r a c t F i l e D i r ( P a r a m S t r ( 0 ) ) , 1 0 2 0 0 ) ; e s c r e v e r A r q u i v o D e T e x t o ( E x t r a c t F i l e D i r ( P a r a m S t r ( 0 ) ) , 1 0 4 0 0 ) ;

Usei um numero grande de linhas para que fosse possvel medir o desempenho. Ao executar a sequencia acima, tive os seguintes arquivos criados no diretrio do executvel de teste: 1 2 1 4 4 7 2 2 7 1 1 _ t o t a l _ l i n h a s _ 1 0 5 0 0 . t x t 1 4 4 7 3 3 0 7 8 _ t o t a l _ l i n h a s _ 1 0 2 0 0 . t x t
1/4

drgarcia1986.wordpress.com/2013/01/31/threads-no-delphi-por-onde-comecar-parte-i/

17/06/13

2 3

Threads no Delphi, por onde comear ? Parte I | Diego Garcia 1 4 4 7 3 3 0 7 8 _ t o t a l _ l i n h a s _ 1 0 2 0 0 . t x t 1 4 4 7 4 3 6 6 1 _ t o t a l _ l i n h a s _ 1 0 4 0 0 . t x t

Sendo assim, podemos concluir que levou cerca de 10 segundos de diferena para cada arquivo. Faremos agora novamente essa rotina, porm, faremos com que ela seja executada dentro de uma thread. Para facilitar nossas vidas, o Delphi j possui o esqueleto padro para a criao de uma thread, basta ir em FILE -> NEW -> OTHER -> THREAD OBJECT, aps selecionar Thread Object ser solicitado o nome da classe da sua Thread (para nosso exemplo utilizei TArquivoTextoInThread) e pronto, teremos o seguinte cdigo j montado em uma nova unit: 1 2 3 4 5 6 7 t y p e T A r q u i v o T e x t o I n T h r e a d=c l a s s ( T T h r e a d ) p r i v a t e {P r i v a t ed e c l a r a t i o n s} p r o t e c t e d p r o c e d u r eE x e c u t e ;o v e r r i d e ; e n d ;

Antes de voltarmos a falar sobre conceitos, vamos primeiro preparar a nossa classe para que ela escreva em um arquivo de texto. Sendo rpido e prtico, criaremos dois atributos privados na classe, um referente ao nmero de linhas a serem escritas e outro referente ao diretrio onde o arquivo ser criado. Feito isso, passaremos a nossa rotina de criar o arquivo de texto para dentro desta classe, ficando desta forma: 1 2 3 4 5 6 7 8 9 1 0 1 1 1 2 t y p e T A r q u i v o T e x t o I n T h r e a d=c l a s s ( T T h r e a d ) p r i v a t e F L i n h a s A I m p r i m i r:i n t e g e r ; F D i r A r q u i v o :S t r i n g ; p r o c e d u r ee s c r e v e r A r q u i v o D e T e x t o ( ) ; f u n c t i o ng e r a r N o m e A r q u i v o ( ) : s t r i n g ; p r o t e c t e d p r o c e d u r eE x e c u t e ;o v e r r i d e ; p u b l i c c o n s t r u c t o rC r e a t e( c o n s tC r e a t e S u s p e n d e d:b o o l e a n ;c o n s tl i n h a s A I m p r i m i r:i n t e g e r e n d ;

Certo, eu fiz algumas coisas a mais, mas vamos por partes, primeiro, vamos ver como ficou nosso mtodo escreverArquivoDeTexto(). 1 2 3 4 5 6 7 8 9 1 0 1 1 1 2 1 3 1 4 1 5 1 6 1 7 p r o c e d u r eT A r q u i v o T e x t o I n T h r e a d . e s c r e v e r A r q u i v o D e T e x t o ; v a r l i n h a s A r q u i v o T e x t o:T S t r i n g L i s t ; I :I n t e g e r ; b e g i n l i n h a s A r q u i v o T e x t o: =T S t r i n g L i s t . C r e a t e ; t r y f o rI: =1t oS e l f . F L i n h a s A I m p r i m i rd o b e g i n l i n h a s A r q u i v o T e x t o . A d d ( f o r m a t ( ' L i n h an u m e r o% d ' , [ i ] ) ) ; S l e e p ( 1 ) ; e n d ; l i n h a s A r q u i v o T e x t o . S a v e T o F i l e ( S e l f . g e r a r N o m e A r q u i v o ( ) ) ; f i n a l l y l i n h a s A r q u i v o T e x t o . F r e e ; e n d ; e n d ;

Basicamente nada mudou, s para melhorar a legibilidade do cdigo foi criado um mtodo para gerar o nome do arquivo de texto, porm ele tem a mesma lgica utilizada anteriormente: 1 2 3 f u n c t i o nT A r q u i v o T e x t o I n T h r e a d . g e r a r N o m e A r q u i v o :s t r i n g ; b e g i n r e s u l t: =F o r m a t ( ' % s \ % s _ t o t a l _ l i n h a s _ % d . t x t ' , [ S e l f . F D i r A r q u i v o , F o r m a t D a t e T i m e ( ' h h m m s s z z z '
2/4

drgarcia1986.wordpress.com/2013/01/31/threads-no-delphi-por-onde-comecar-parte-i/

17/06/13

Threads no Delphi, por onde comear ? Parte I | Diego Garcia

e n d ;

Sendo assim, at aqui nenhuma novidade, mas agora vamos para um pouco de conceitos analisando o construtor que fiz para a classe: 1 2 3 4 5 6 7 8 c o n s t r u c t o rT A r q u i v o T e x t o I n T h r e a d . C r e a t e ( c o n s tC r e a t e S u s p e n d e d :b o o l e a n ; c o n s tl i n h a s A I m p r i m i r :i n t e g e r ;c o n s td i r A r q u i v o:s t r i n g ) ; b e g i n S e l f . F L i n h a s A I m p r i m i r: =l i n h a s A I m p r i m i r ; S e l f . F D i r A r q u i v o : =d i r A r q u i v o ; S e l f . F r e e O n T e r m i n a t e : =t r u e ; i n h e r i t e dC r e a t e ( C r e a t e S u s p e n d e d ) ; e n d ;

A classe TThread possui uma propriedade booleana chamada FreeOnTerminate que quando alterada para true a thread liberada automaticamente da memria aps a sua execuo. Outra coisa que importante de notar o parmetro CreateSuspended que o construtor da classe TThread recebe, ele basicamente define se a thread ser criada suspensa ou no, ou seja, se a thread ser executada automaticamente aps a instncia ser criada (CreateSuspended = false) ou se ser necessrio iniciar a execuo da thread de forma manual (CreateSuspended = true) atravs do mtodo Start. Para completar a implementao da nossa classe, vamos ver como ficou o mtodo Execute() da thread: 1 2 3 4 p r o c e d u r eT A r q u i v o T e x t o I n T h r e a d . E x e c u t e ; b e g i n e s c r e v e r A r q u i v o D e T e x t o ( ) ; e n d ;

Ok, imagino que voc esperava mais do que simplesmente uma chamada para o mtodo escreverArquivoDeTexto() porm, o segredo todo est ai, o mtodo Execute() exatamente o mtodo que ser executado assim que a thread for iniciada. Com isso, a nossa thread est pronta. Agora vamos fazer o mesmo teste que fizemos anteriormente mas dessa vez utilizando nossa thread: 1 2 3 4 5 6 7 8 9 v a r o A r q u i v o T e x t o I n T h r e a d 1:T A r q u i v o T e x t o I n T h r e a d ; o A r q u i v o T e x t o I n T h r e a d 2:T A r q u i v o T e x t o I n T h r e a d ; o A r q u i v o T e x t o I n T h r e a d 3:T A r q u i v o T e x t o I n T h r e a d ; b e g i n o A r q u i v o T e x t o I n T h r e a d 1: =T A r q u i v o T e x t o I n T h r e a d . C r e a t e ( f a l s e , 1 0 5 0 0 , E x t r a c t F i l e P a t h ( P a r a m S t r ( o A r q u i v o T e x t o I n T h r e a d 2: =T A r q u i v o T e x t o I n T h r e a d . C r e a t e ( f a l s e , 1 0 2 0 0 , E x t r a c t F i l e P a t h ( P a r a m S t r ( o A r q u i v o T e x t o I n T h r e a d 3: =T A r q u i v o T e x t o I n T h r e a d . C r e a t e ( f a l s e , 1 0 4 0 0 , E x t r a c t F i l e P a t h ( P a r a m S t r ( e n d ;

Executando a rotina acima, como determinei que minha thread no ir iniciar suspensa, tive os seguintes arquivos criados no diretrio do executvel: 1 2 3 1 5 4 2 4 6 9 4 6 _ t o t a l _ l i n h a s _ 1 0 2 0 0 1 5 4 2 4 7 1 6 7 _ t o t a l _ l i n h a s _ 1 0 4 0 0 1 5 4 2 4 7 2 5 6 _ t o t a l _ l i n h a s _ 1 0 5 0 0

Note que o ltimo arquivo a ser criado foi o de 10500 linhas mesmo sendo o primeiro a ter sua rotina executada e outra coisa muito importante a diferena de tempo na criao dos arquivos, se antes sem thread tivemos uma demora de 10 segundos para cada arquivo, aqui no passou de poucos milsimos, tivemos esse resultado pois cada arquivo demora cerca de 10 segundos para ser gerado, porm, como os 3 estavam sendo gerados ao mesmo tempo de forma paralela, no foi necessrio utilizar uma fila de processamento. Como o intuito deste post foi s demonstrar o uso de threads, no entrei em mais detalhes, porm, na prxima parte veremos um pouco mais sobre como controlar o ciclo de vida de uma thread.

drgarcia1986.wordpress.com/2013/01/31/threads-no-delphi-por-onde-comecar-parte-i/

3/4

17/06/13

Threads no Delphi, por onde comear ? Parte I | Diego Garcia


About these ads

Share this:

Twitter 1

Facebook 2

Google +1

Curtir isso:

Gosto
Be the first to like this.

Sobre Diego Garcia Analista/Desenvolvedor Delphi desde 2008, bacharel em Cincia da Computao e entusiasta de metodologias geis e engenharia de software. Ver todas as mensagens por Diego Garcia

Esse post foi publicado em Programao e marcado Delphi, thread. Guardar link permanente.

4 respostas para Threads no Delphi, por onde comear ? Parte I


Pingback: Threads no Delphi, por onde comear ? Parte II | Diego Garcia

Pingback: Threads no Delphi, por onde comear ? Parte III | Diego Garcia

Samuel Rodrigues disse:


27/04/2013 s 12:51 am

Ol, boa noite! Gostei muito do tutorial e segui ele cada detalhe. S tive um problema com a 4 parte, com o TThread.CreateAnonymousThread. gerado um erro reportando que Tthread no contem o CreateAnonymousThread. Uso o Delphi2010, ele no possui essa funo? Obrigado!
Resposta

Diego Garcia disse:


27/04/2013 s 1:53 am

Opa Samuel, tudo bem? fico feliz que tenha gostado e tenha seguido os artigos Sobre as threads anonimas tenho quase certeza que esse recurso est disponvel no delphi a partir da verso XE, ou seja, uma acima da que voc est usando infelizmente. []s
Resposta

Diego Garcia
Tema: Twenty Ten Blog no WordPress.com.

drgarcia1986.wordpress.com/2013/01/31/threads-no-delphi-por-onde-comecar-parte-i/

4/4