Você está na página 1de 13

UNIVERSIDADE DO ESTADO DA BAHIA UNEB

LABORATRIO DE ORIENTAO A OBJETOS - OOLAB


Evitando conflitos
em aplicaes
multi-thread
no
Delphi/Kylix
Edmilson dos Santos de Jesus
Salvador, maro de 2002.
UNIVERSIDADE DO ESTADO DA BAHIA UNEB
Laboratrio de Orientao a Objetos OOLAB http://www.uneb.net/oolab
- 1 -
NDICE
Agradecimentos................................................................ ................................ ................................ ............ 2
Aplicaes multi-thread................................................................ ................................ ................................ 3
Evitando conflitos com mltiplas threads ................................................................ ................................ ...... 5
Utilizando a Thread Principal atravs do mtodo Synchronize................................................................ ...... 6
Usando o Lock de Objetos ................................................................ ................................ ............................ 7
Protegendo sees crticas atravs da classe TCriticalSection ................................................................ ........ 7
Utilizando mltipla leitura e exclusiva escrita................................. ................................ ............................... 8
Concluses ................................................................ ................................ ................................ ................. 10
Bibliografia ................................................................ ................................ ................................ ................ 11
Autor................................................................ ................................ ................................ .......................... 12
UNIVERSIDADE DO ESTADO DA BAHIA UNEB
Laboratrio de Orientao a Objetos OOLAB http://www.uneb.net/oolab
- 2 -
Agradecimentos
Quero agradecer a todos que contriburam direta e indiretamente na
elaborao desse artigo. Aos colegas do OOLAB (Laboratrio de Orientao a
Objetos UNEB ), pela fora que me deram, ao Mestre Jorge Farias pela
orientao, a Borland por ter feito um Help to preciso para o Kylix e o Delphi, a
Andrew S. Tanenbaum, por ser to claro e direto no livro Sistemas Operacionais
Modernos.
Os obstculos existem para que sejam vencidos. E afinal o que seria da
vida sem os obstculos?
UNIVERSIDADE DO ESTADO DA BAHIA UNEB
Laboratrio de Orientao a Objetos OOLAB http://www.uneb.net/oolab
- 3 -
Aplicaes multi-thread
Aplicaes Multi-thread so aplicaes que incluem vrias linhas
simultneas de execuo. Com somente uma thread a aplicao deve parar sua
execuo quando estiver esperando por um processo lento tal como leitura de
disco, comunicao com outra mquina, ou exibio de contedo multimdia. Com
mltiplas threads a mesma aplicao pode continuar executando as outras threads
enquanto a thread lenta espera pelo resultado de um processo.
Para construir aplicaes multi-thread no Delphi/Kylix voc deve criar uma
nova classe descendente de TThread, e cada instncia dessa nova classe ser
uma linha de execuo que alocar tempo de CPU para o seu processamento.
Para criar uma
nova classe
descendente de
TThread selecione
no menu principal do
Delphi File | New, ou
no caso do Kylix File
| New | Other, na
caixa de dilogo que
aparece selecione
Thread Object,
dever aparecer uma
janela para voc
colocar o nome da
classe que ser
criada.
Depois que voc colocar o nome, o Delphi/Kylix automaticamente criar
uma nova unit para a implementao da thread.
UNIVERSIDADE DO ESTADO DA BAHIA UNEB
Laboratrio de Orientao a Objetos OOLAB http://www.uneb.net/oolab
- 4 -
Veja o exemplo abaixo, o corpo da unit gerada pelo Delphi para a classe
TThreadTeste.
Depois disso voc pode colocar o cdigo que a thread executar no mtodo
Execute. Para utilizar a classe criada em outras units basta acrescentar o nome da
unit na clausula uses das outras units, e pode usar classe que voc criou. Veja
abaixo o exemplo do uso da classe TThreadTeste.
unit UnitPrincipal;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, Unit1;
type
TFormPrincipal = class(TForm)
ButtonCriarThread: TButton;
procedure ButtonCriarThreadClick(Sender: TObject);
UNIVERSIDADE DO ESTADO DA BAHIA UNEB
Laboratrio de Orientao a Objetos OOLAB http://www.uneb.net/oolab
- 5 -
private
{ Private declarations }
public
{ Public declarations }
end;
var
FormPrincipal: TFormPrincipal;
Teste:TThreadTeste; //aqui declaramos a varivel Teste do tipo TThreadTeste
implementation
{$R *.dfm}
procedure TFormPrincipal.ButtonCriarThreadClick(Sender: TObject);
begin
Teste:=TThreadTeste.Create(False); //Aqui instanciamos a nova thread
end;
end.
Evitando conflitos com mltiplas threads
Quando usamos objetos da VCL e da CLX em uma aplicao multi-thread,
no temos garantia de que os mtodos e propriedades desses objetos sero
acessados apenas por uma thread de cada vez, o cdigo da aplicao que deve
garantir isso. Esses mtodos e propriedades podem executar aes sobre a
memria a qual no est protegida da ao de outras threads.
Vamos supor que temos uma aplicao onde vrias threads acessam a
mesma lista para inserir ou remover itens da mesma, obvio que duas thread no
podem inserir ou remover itens da lista ao mesmo tempo, se isso ocorrer podem
acontecer erros inesperados, ou pior, pode no ocorrer erro algum e o programa
no funcionar corretamente, nesse caso o resultado final do processamento
depender de quem executou quando, isso chamado de condio de corrida.
Para evitar conflitos, as threads devem acessar os objetos de forma sincronizada.
A maioria dos mtodos que acessam objetos da VCL ou da CLX e
atualizam os formulrios devem ser chamados somente pela thread principal ou
utilizando um objeto de sincronizao tal como os objetos instanciados a partir das
classes TMultiReadExclusiveWriteSynchronizer ou TCriticalSection.
UNIVERSIDADE DO ESTADO DA BAHIA UNEB
Laboratrio de Orientao a Objetos OOLAB http://www.uneb.net/oolab
- 6 -
Utilizando a Thread Principal atravs do mtodo Synchronize
Se voc acessa os mtodos e propriedades dos objetos a partir de uma
nica thread voc no precisa se preocupar com erros causados por acesso
simultneo, como valores lidos incorretamente ou violao de acesso.
Para fazer com que um mtodo de outra thread use a thread principal para
executar uma ao, voc deve utilizar o mtodo Synchronize. Para fazer isso crie
uma rotina separada que executa a ao desejada, e depois chame-a de dentro
da thread utilizando o mtodo Synchronize e passando como parmetro o nome
da rotina que voc criou, veja o exemplo abaixo.
Synchronize causa uma chamada especfica ao mtodo passado como
parmetro utilizando a thread principal, evitando conflitos entre as threads.
Synchronize espera a thread principal entrar na mensagem de loop e ento
executa o mtodo passado como parmetro.
OBS: Porque o mtodo Synchronize utiliza a mensagem de loop ele no
pode ser utilizado em uma aplicao console. Voc deve utilizar outros
mecanismos, tal como seo crtica, para proteger o acesso a objetos em
aplicaes console.
Evite na medida do possvel o uso de Synchronize, isso dever aumentar a
performance da sua aplicao pois muitas vezes voc no precisa esperar a
thread principal entrar na mensagem de loop para executar o mtodo de outra
thread.
UNIVERSIDADE DO ESTADO DA BAHIA UNEB
Laboratrio de Orientao a Objetos OOLAB http://www.uneb.net/oolab
- 7 -
Usando o Lock de Objetos
Alguns objetos tem proteo prpria para evitar que mais de uma thread
utilize a instncia desses objetos ao mesmo tempo. Por exemplo o TCanvas tem o
mtodo Lock que evita que outras threads acessem o canvas at que o mtodo
Unlock seja chamado.
Voc deve proteger o Canvas com um Lock em todas as chamadas que o
utilizam e depois voc deve chamar o mtodo Unlock para liber-lo para outras
threads.
Quando o mtodo Lock chamado ele verifica se o Canvas j est
bloqueado e se estiver Lock espera at que o Canvas seja liberado atravs da
chamada ao mtodo Unlock pela mesma thread que o bloqueou.
Protegendo sees crticas atravs da classe TCriticalSection
Se um objeto no possui mtodo prprio para proteo voc pode utilizar a
classe TCriticalSection para proteger uma seo crtica.
UNIVERSIDADE DO ESTADO DA BAHIA UNEB
Laboratrio de Orientao a Objetos OOLAB http://www.uneb.net/oolab
- 8 -
Seo crtica uma parte do programa cujo processamento pode levar
ocorrncia de condies de corrida. Para utilizar seo crtica voc deve criar
uma instncia global da classe TCriticalSection, acrescentando na clusula uses a
unit StdCtrls.
TCriticalSection tem dois mtodos, Acquire (que impede que as outras
threads entrem na seo) e Release (que remove o bloqueio).
Utilizando mltipla leitura e exclusiva escrita.
Existe uma situao especial onde muitas threads precisam ler o valor de
determinada regio de memria e que raramente uma thread escreve nessa
regio, nesse caso podemos utilizar uma instncia global da classe
TMultiReadExclusiveWriteSynchronizer.
A classe TMultiReadExclusiveWriteSynchronizer tem os mtodos
BeginRead e EndRead para proteger um bloco que pode ser acessado por vrias
threads desde que nenhuma outra thread esteja dentro de uma seo BeginWrite
EndWrite. Os mtodos BeginWrite e EndWrite protegem uma parte do programa
que acessa e modifica a memria. Vrias threads podem entrar na seo
BeginRead-EndRead ao mesmo tempo desde que nenhuma outra thread esteja
dentro de uma seo BeginWrite-EndWrite.
UNIVERSIDADE DO ESTADO DA BAHIA UNEB
Laboratrio de Orientao a Objetos OOLAB http://www.uneb.net/oolab
- 9 -
Se uma thread A tentar executar BeginWrite e a thread B estiver dentro de
uma seo BeginRead-EndRead, a thread A vai dormir, at que a thread B
execute EndRead e s ento a thread A prosseguir. Se a thread B executar
BeginRead e a thread A estiver dentro de uma seo BeginWrite-EndWrite, a
thread B vai dormir at que a thread A execute EndWrite. Veja abaixo.
UNIVERSIDADE DO ESTADO DA BAHIA UNEB
Laboratrio de Orientao a Objetos OOLAB http://www.uneb.net/oolab
- 10 -
Concluses
Desenvolver uma aplicao multi-thread no Delphi/Kylix relativamente
fcil, mas o difcil mesmo garantir a consistncia do programa, trabalhar com
threads requer por parte do desenvolvedor muito mais ateno, para se ter uma
idia, em alguns casos atualizar um formulrio pode se tornar mais difcil do que
criar e manter uma lista generalizada, principalmente se o programador no for
experiente.
Em muitas aplicaes o uso de threads se faz necessrio, para garantir a
performance e muitas vezes at o prprio funcionamento da aplicao. Existem
aplicaes que s so concebeis atravs do uso de multi-thread.
UNIVERSIDADE DO ESTADO DA BAHIA UNEB
Laboratrio de Orientao a Objetos OOLAB http://www.uneb.net/oolab
- 11 -
Bibliografia
Sistemas Operacionais Modernos, Andrew S. Tanenbaum1999.
O Help do Delphi.
O Help do Kylix.
UNIVERSIDADE DO ESTADO DA BAHIA UNEB
Laboratrio de Orientao a Objetos OOLAB http://www.uneb.net/oolab
- 12 -
Autor
Edmilson dos Santos de Jesus
Edsjbr@yahoo.com.br
Estudante do curso de Bacharelado em Anlise de Sistemas 8 Sem. UNEB-BA
http://www.uneb.br
Integrante do OOLAB-UNEB (Laboratrio de Orientao a Objetos da UNEB)
http://www.uneb.net/oolab
Analista de Sistemas da Actha Multiformtica
http://www.actha.com.br

Você também pode gostar