DEL420 Zaawansowane programowanie w (pakiecie) Delphi Andrzej Marciniak Prezentacja multimedialna przygotowana za pomoc¹ systemu Corel Presentations 11 Copyright 2004-2010 by Andrzej Marciniak DEL-11(1 z 59)
Na poprzednim wyk³adzie... wywo³anie innego programu z programu paskalowego przegl¹d funkcji i procedur modu³u Math funkcje i procedury trygonometryczne, hiperboliczne, area funkcje, funkcje logarytmiczne, wyk³adnicze i potêgowe funkcje i procedury do obliczeñ statystycznych inne funkcje modu³u Math sprawdzanie obecnoœci poprzedniego egzemplarza programu DEL-11(2 z 59)
Na tym wyk³adzie... wielozadaniowoœæ w œrodowisku Windows programowanie sterowane zdarzeniami wysy³anie wiadomoœci do okienek (funkcje PostMessage i SendMessage) obs³uga wiadomoœci przetwarzanie w tle wielow¹tkowoœæ pojêcie procesu i w¹tku zmienne w¹tkowe klasa TThread priorytety w¹tków synchronizacja w¹tków DEL-11(3 z 59)
Wielozadaniowoœæ... Programowanie sterowane zdarzeniami Œrodowisko Windows w wersji 32-bitowej pozwala na jednoczesne uruchamianie wielu programów oraz aktywacjê wielu w¹tków dla jednego programu. Podstawowa koncepcja programowania sterowanego zdarzeniami polega na tym, e przebieg programu determinuj¹ zdarzenia. Program spêdza wiêkszoœæ czasu oczekuj¹c na te zdarzenia i posiada kod na nie reaguj¹cy. Zdarzenia s¹ uszeregowane ka de zdarzenie jest obs³ugiwane dopiero po zakoñczeniu obs³ugi poprzedniego. Zdarzenia s¹ w œrodowisku Windows identyfikowane przez wiadomoœci. DEL-11(4 z 59)
Wielozadaniowoœæ... Programowanie sterowane zdarzeniami W 16-bitowym œrodowisku Windows 3.1 nie by³o mo liwoœci przerwania procedury obs³ugi wiadomoœci. W Windows 9x, NT, 2000, Me i XP po up³ywie ustalonego czasu system przekazuje wiadomoœæ do obs³ugi do kolejnej aplikacji na liœcie. Dopiero, gdy skoñcz¹ dzia³anie wszystkie aplikacje, wznawiana jest pierwsza z nich. Nazywa siê to wielozadaniowoœci¹ z wyw³aszczaniem. Po obs³u eniu wiadomoœci program staje siê nieaktywny do chwili otrzymania innej wiadomoœci (chyba e stosuje siê wielow¹tkowoœæ bêdzie dalej). DEL-11(5 z 59)
Wielozadaniowoœæ... Programowanie sterowane zdarzeniami Dla programu uruchomionego w œrodowisku Windows zdarzenia wejœciowe (spowodowane przez myszkê lub klawiaturê) generuj¹ jedynie niewielk¹ czêœæ ca³kowitego przep³ywu wiadomoœci wiêkszoœæ komunikatów to wewnêtrzne wiadomoœci œrodowiska Windows i wiadomoœci wymieniane pomiêdzy ró nymi elementami steruj¹cymi i oknami. Do œledzenia wiadomoœci mo na wykorzystaæ program WinSight (dostêpny w pakiecie Delphi). W programie tym nale y wybraæ polecenie Message Trace, nastêpnie wyœwietlenie wiadomoœci dla wszystkich okien, po czym wybraæ polecenie Start. Wykonuj¹c dalej zwyk³e operacje za pomoc¹ myszy mo na w ci¹gu kilku sekund zobserwowaæ setki komunikatów. DEL-11(6 z 59)
Wielozadaniowoœæ... Wysy³anie wiadomoœci do okien W œrodowisku Windows s¹ dwa ró ne sposoby wysy³ania wiadomoœci do okien: za pomoc¹ funkcji API PostMessage s³u y do umieszczenia wiadomoœci w kolejce wiadomoœci programu; wiadomoœæ zostanie obs³u ona tylko wówczas, gdy dany program przejmie sterowanie od systemu i tylko po obs³u eniu wczeœniejszych wiadomoœci (jest to wywo³anie asynchroniczne, gdy nie wiadomo, kiedy wiadomoœæ bêdzie rzeczywiœcie odebrana), DEL-11(7 z 59)
Wielozadaniowoœæ... Wysy³anie wiadomoœci do okien W œrodowisku Windows s¹ dwa ró ne sposoby wysy³ania wiadomoœci do okien: za pomoc¹ funkcji API SendMessage s³u y do natychmiastowego wykonania kodu procedury obs³ugi wiadomoœci; funkcja ta omija kolejkê wiadomoœci programu i wysy³a wiadomoœæ bezpoœrednio do docelowego okna lub elementu steruj¹cego (jest to wywo³anie synchroniczne). Ró nica pomiêdzy tymi sposobami wysy³ania wiadomoœci przypomina ró nicê pomiêdzy wys³aniem poczt¹ listu, który dotrze do miejsca przeznaczenia wczeœniej lub póÿniej, a wys³aniem faksu, który dociera natychmiast do odbiorcy. DEL-11(8 z 59)
Wielozadaniowoœæ... Wysy³anie wiadomoœci do okien Wywo³anie funkcji PostMessage ma postaæ PostMessage (identyfikator, wiadomoœæ, WParam, LParam) gdzie: identyfikator (typu HWND identycznego z typem THandle i Longword) identyfikator okna nadawany przez œrodowisko Windows (sposób uzyskania tego identyfikatora zob. poprzedni wyk³ad), wiadomoœæ (typu UINT identycznego z typem Longword) okreœla przesy³an¹ wiadomoœæ (najczêœciej za pomoc¹ sta³ej o przedrostku wm_), WParam i LParam (typów odpowiednio WPARAM i LPARAM identycznych z typem Longint) okreœlaj¹ dodatkowe informacje zwi¹zane z dan¹ wiadomoœci¹. DEL-11(9 z 59)
Wielozadaniowoœæ... Wysy³anie wiadomoœci do okien Funkcjê SendMessage wywo³uje siê z takimi samymi parametrami: SendMessage (identyfikator, wiadomoœæ, WParam, LParam) Wiadomoœci œrodowiska Windows s¹ identyfikowane za pomoc¹ sta³ych, a przesy³ane w rekordach o ogólnym, predefiniowanym typie TMessage (jest on zdefiniowany w module Messages): DEL-11(10 z 59)
Wielozadaniowoœæ... Wysy³anie wiadomoœci do okien type TMessage = packed record Msg : Cardinal; case Integer of 0 : (WParam : Longint; LParam : Longint; Result : Longint); 1 : (WParamLo : Word; WParamHi : Word; LParamLo : Word; LParamHi : Word; ResultLo : Word; ResultHi : Word); end; Pole Msg s³u y do przechowywaniai dentyfikatora wiadomoœci, pola WParam i LParam s¹ przeznaczone do przesy³aniadodatkowych informacji zwi¹zanych z dan¹ wiadomoœci¹, a pole Result s³u y do przekazywania informacji po obs³u eniu wiadomoœci. Z uwagi na deklaracjê wariantow¹ w rekordzie, programista ma dostêp do mniej i bardziej znacz¹cych s³ów pól WParam, LParam i Result. Uwaga: Standardowe wiadomoœci œrodowiska Windows maj¹ swoje w³asne typy rekordowe, których pola maj¹ nazwy adekwatne do przesy³anych informacji. Nazwy tych typów rozpoczynaj¹ siê od przedrostka TWM. Jednak ka dy rekord wiadomoœci przez zmianê typu mo e byæ przekszta³cony na rekord typu TMessage. DEL-11(11 z 59)
Wielozadaniowoœæ... Obs³uga wiadomoœci Metoda s³u ¹ca do obs³ugi wiadomoœci powinna byæ zadeklarowana w sekcji private definicji typu klasowego i musi byæ metod¹-procedur¹. Deklaracja takiej metody zawiera dyrektywê jêzyka message, po której wystêpuje sta³a ca³kowita okreœlaj¹ca wiadomoœæ (na ogó³ sta³¹ tê okreœla siê za pomoc¹ identyfikatora, którego nazwa kojarzy siê z obs³ugiwan¹ wiadomoœci¹). Metody obs³uguj¹ce wiadomoœci nie mog¹ byæ pokrywane przy u yciu dyrektywy jêzyka override. Ewentualne pokrycie takiej metody w typie potomnym jest jednoznacznie okreœlone przez sta³¹ podan¹ po dyrektywie message. DEL-11(12 z 59)
Przyk³ad Wielozadaniowoœæ... Obs³uga wiadomoœci type TOkno = class (TForm)... private procedure WMSize (var wiadomosc : TWMSize); message WM_SIZE;... end; DEL-11(13 z 59)
Wielozadaniowoœæ... Obs³uga wiadomoœci Definicja metody obs³uguj¹cej wiadomoœæ ma postaæ tak¹ sam¹, jak definicja ka dej innej metody. Opcjonalnie mo e ona zawieraæ instrukcjê dziedziczenia sk³adaj¹c¹ siê z samego s³owa kluczowego inherited. Wyst¹pienie tej instrukcji powoduje przekazanie rekordu z wiadomoœci¹ (okreœlonego przez parametr) do metody dziedziczonej. Je eli w adnym z nadrzêdnych typów klasowych nie okreœlono metody obs³uguj¹cej dan¹ wiadomoœæ, to nast¹pi wywo³anie metody DefaultHandler, która jest zdefiniowana w typie TObject i tym samym dostêpna w ka dym typie klasowym. U ycie instrukcji inherited powoduje zatem, e wiadomoœæ zawsze zostanie obs³u ona. DEL-11(14 z 59)
Przyk³ady Wielozadaniowoœæ... Obs³uga wiadomoœci 1) procedure TOkno.WMSize (var wiadomosc : TWMSize); begin if warunek then... else inherited end; 2) procedure TOkno.WMSize (var wiadomosc : TWMSize); begin instrukcje inherited end; DEL-11(15 z 59)
Wielozadaniowoœæ... Obs³uga wiadomoœci Oprócz funkcji PostMessage i SendMessage do wywo³ania metody obs³ugi wiadomoœci mo na tak e zastosowaæ metodê-procedurê Dispatch (zdefiniowan¹ w typie TObject). Wywo³anie metody Dispatch ma postaæ Dispatch (wiadomoœæ) gdzie wiadomoœæ oznacza rekord (dok³adniej: zmienn¹ nieokreœlonego typu), którego pierwsze pole (cztery bajty) powinno byæ typu Cardinal. Wartoœæ tego pola identyfikuje wysy³an¹ wiadomoœæ. Pozosta³e pola rekordu mog¹ zawieraæ informacje specyficzne dla przetwarzanej wiadomoœci. DEL-11(16 z 59)
Wielozadaniowoœæ... Obs³uga wiadomoœci Wywo³anie metody Dispatch powoduje wywo³anie najbli szej metody obs³uguj¹cej dan¹ wiadomoœæ. Metoda ta jest poszukiwana najpierw w klasie, w której nast¹pi³o wywo³anie metody Dispatch, nastêpnie w klasie bezpoœrednio nadrzêdnej, po czym w kolejnej klasie poprzedniej (przodku) itd., a do osi¹gniêcia klasy TObject. Jeœli po drodze nie napotkano w³aœciwej metody, to nast¹pi wywo³anie standardowej metody obs³ugi DefaultHandler zdefiniowanej w klasie TObject. DEL-11(17 z 59)
Wielozadaniowoœæ... Przetwarzanie w tle Za³ó my, e musimy zaimplementowaæ czasoch³onny algorytm. Jeœli napiszemy go w odpowiedzi na zdarzenie, program bêdzie zablokowany na czas wykonywania algorytmu. Aby u ytkownik wiedzia³, e coœ siê dzieje mo emy np. wyœwietliæ kursor w kszta³cie klepsydry, ale nie jest to rozwi¹zanie zbyt przyjazne. Œrodowisko Windows (32-bitowe) umo liwia wprawdzie innym programom kontynuowanie wykonywania, ale dany program bêdzie wówczas unieruchomiony. Z kolei podczas wykonywania algorytmu program nie bêdzie móg³ otrzymywaæ i przetwarzaæ adnych innych wiadomoœci. DEL-11(18 z 59)
Wielozadaniowoœæ... Przetwarzanie w tle Prostym rozwi¹zaniem tego problemu jest wielokrotne wywo³anie w algorytmie bezparametrowej metody ProcessMessages obiektu Application, zwykle w wewnêtrznej pêtli. Wywo³anie tej metody zatrzymuje wykonanywanie algorytmu, pozwala programowi na otrzymanie i obs³ugê wiadomoœci, a nastêpnie wznowienie wykonywania. Problem przy takim rozwi¹zaniu polega jednak na tym, e w chwili zatrzymania programu (w celu odebrania wiadomoœci), u ytkownik mo e wykonaæ dowoln¹ operacjê i móg³by na przyk³ad wybraæ przycisk, który uruchomi³ algorytm. DEL-11(19 z 59)
Wielozadaniowoœæ... Przetwarzanie w tle Inny sposób polega na u yciu zdarzenia OnIdle dla obiektu Application. Ró nica pomiêdzy wywo³aniem metody ProcessMessages a u yciem zdarzenia OnIdle polega na tym, e w pierwszym przypadku program bêdzie mia³ wiêcej czasu na przetwarzanie ni w drugim. Wywo³anie metody ProcessMessages pozwala systemowi na wykonanie innych operacji w trakcie wykonywania obliczeñ przez program, a zastosowanie zdarzenia OnIdle pozwala programowi na wykonywanie zadañ w tle, gdy brak jest oczekuj¹cych adañ ze strony u ytkownika. DEL-11(20 z 59)
Wielow¹tkowoœæ Pojêcie procesu i w¹tku Wykonanie programu, który ma swój kod i dane, zajmuje w³asn¹, wirtualn¹ przestrzeñ adresow¹ oraz korzysta z zasobów systemowych, nazywa siê procesem. Na proces mo e sk³adaæ siê jeden lub kilka w¹tków. W¹tek jest podstawow¹ jednostk¹, której system operacyjny przydziela czas procesora. Jest on niezale n¹ œcie k¹ wykonywania czêœci kodu programu wewn¹trz procesu. DEL-11(21 z 59)
Wielow¹tkowoœæ Pojêcie procesu i w¹tku W¹tek mo e wykonaæ dowoln¹ czêœæ kodu programu, w tym czêœæ, która jest ju wykonywana przez inny w¹tek. W szystkie w¹tki programu wykorzystuj¹ tê sam¹ wirtualn¹ przestrzeñ adresow¹, zmienne globalne i zasoby systemowe procesu. Oprócz tego ka dy w¹tek posiada swoje w³asne rejestry, w³asny stos i w³asny mechanizm wejœcia, w tym w³asn¹ kolejkê wiadomoœci. DEL-11(22 z 59)
Wielow¹tkowoœæ Pojêcie procesu i w¹tku Wady wielow¹tkowoœci: powoduje, e program dzia³a wolniej, chyba e jest kilka procesorów i system operacyjny mo e rozdzieliæ w¹tki miêdzy nimi, Ÿle napisane programy wielow¹tkowe mog¹ dzia³aæ wolniej w systemach wieloprocesorowych ni w systemie z jednym procesorem, gdy synchronizacja w¹tków zu ywa o wiele wiêcej zasobów w systemach wieloprocesorowych, programy wielow¹tkowe musz¹ synchronizowaæ dostêp do wspólnych zasobów i pamiêci, co powoduje, e jest je o wiele trudniej napisaæ. DEL-11(23 z 59)
Wielow¹tkowoœæ Pojêcie procesu i w¹tku Zalety wielow¹tkowoœci: mo na uruchomiæ w¹tek w tle, pozwalaj¹c u ytkownikowi na obs³ugê programu, mo na spowodowaæ, e jeden w¹tek bêdzie dzia³a³ szybciej ni inne przez ustawienie jego priorytetu, mo na regulowaæ dostêp ró nych w¹tków do zasobów, przydzielaæ lokaln¹ pamiêæ dla ka dego w¹tku i uruchamiaæ wiele w¹tków tego samego typu. Operacja, któr¹ warto umieœciæ w w¹tku drugoplanowym to taka, której wykonanie zajmuje procesorowi du o czasu i jest doœæ odizolowana jeœli chodzi o dostêp do danych. DEL-11(24 z 59)
Wielow¹tkowoœæ Zmienne w¹tkowe W module System zdefiniowano funkcjê BeginThread i procedurê EndThread, które dotycz¹ obs³ugi w¹tków. Zwykle funkcji tej i procedury nie u ywa siê bezpoœrednio, a zamiast tego korzysta siê z klasy TThread okreœlonej w module Threads biblioteki VCL. Z obs³ug¹ w¹tków s¹ zwi¹zane zmienne w¹tkowe, które deklaruje siê nastêpuj¹co: threadvar sekwencja-deklaracji Deklaracja jakiejœ zmiennej jako w¹tkowej oznacza, e jest ona zmienn¹ lokaln¹ w ramach w¹tku (wartoœci przypisane jej w w¹tku s¹ tracone po zakoñczeniu wykonywania w¹tku). DEL-11(25 z 59)
Wielow¹tkowoœæ Klasa TThread S³u y do kontrolowania w¹tków. Nie u ywa siê jej bezpoœrednio, gdy jest to klasa z metod¹ abstrakcyjn¹ Execute. Aby stosowaæ w¹tki, zawsze tworzy siê klasê potomn¹ od TThread i wykorzystuje odpowiednie elementy tej klasy bazowej: # konstruktor Create o wywo³aniu Create (zawieszenie) gdzie parametr jest typu Boolean decyduje o tym, czy uruchomiæ w¹tek natychmiast, czy te zawiesiæ go na póÿniej, DEL-11(26 z 59)
Wielow¹tkowoœæ Klasa TThread # bezparametrowe metody synchronizacji (publiczne) # w³asnoœci Resume Suspend Terminate WaitFor Priority rozpoczêcie (procedura) zawieszenie (procedura) przerwanie (funkcja) oczekiwanie (funkcja) priorytet typu wyliczeniowego: type TThreadPriority = (tpidle, tplowest, tplower, tpnormal, tphigher, tphighest, tptimecritical); DEL-11(27 z 59)
# w³asnoœci (cd.) Suspended Terminated Handle ThreadID Wielow¹tkowoœæ zawieszenie ( Boolean) przerwanie ( Boolean) (tylko do odczytu) (tylko do odczytu) Klasa TThread # metody chronione (sekcja protected) Execute metoda abstrakcyjna (musi byæ zdefiniowana w ka dej klasie potomnej, gdy zawiera g³ówny kod w¹tku), DEL-11(28 z 59)
# metody chronione (cd.) Wielow¹tkowoœæ Klasa TThread Synchronize ma na celu unikniêcie jednoczesnego dostêpu do komponentów VCL, a jej wywo³anie ma postaæ Synchronize (metoda) gdzie parametr metoda jest metod¹ klasow¹ (wykonywan¹ dla g³ównego w¹tku) DEL-11(29 z 59)
Wielow¹tkowoœæ Przyk³ad 1 (wykorzystanie metody Synchronize) Przyk³ady W¹tek s³u y do malowania kolorowych pikseli na formatce. W klasie w¹tku TPainterThread (klasa potomna klasy TThread) zdefiniowano metodê Execute (pokrywa ona metodê abstrakcyjn¹ z klasy TThread) oraz metodê Paint, która umo liwia dostêp do obiektów VCL (dlatego jest ona wywo³ywana tylko z metody Synchronize). DEL-11(30 z 59)
Wielow¹tkowoœæ Przyk³ad 1 (wykorzystanie metody Synchronize) Przyk³ady type TPainterThread = class (TThread) private X, Y : Integer; protected procedure Execute; override; procedure Paint; end; procedure TPainterThread.Paint; begin Form1.Canvas.Pixels[X,Y]:=clYellow end; DEL-11(31 z 59)
Wielow¹tkowoœæ Przyk³ad 1 (wykorzystanie metody Synchronize) procedure TPainterThread. Execute; begin Randomize; repeat X:=Random(Form1.ClientWidth); Y:=Random(Form1.ClientHeight); Synchronize (Paint) until Terminated end; Przyk³ady DEL-11(32 z 59)
Wielow¹tkowoœæ Przyk³ad 1 (wykorzystanie metody Synchronize) Przyk³ady Na formatce umieszczamy dwa przyciski: jeden uruchamiaj¹cy w¹tek i drugi zatrzymuj¹cy w¹tek (oprogramowujemy zdarzenia OnClick tych przycisków). W metodzie obs³ugi zdarzenia OnClick pierwszego przycisku umieszczamy wywo³anie konstruktora: PT:=TPainterThread. Create (False); pole prywatne w klasie opisuj¹cej formatkê powoduje natychmiastowe uruchomienie w¹tku DEL-11(33 z 59)
Wielow¹tkowoœæ Przyk³ad 1 (wykorzystanie metody Synchronize) W metodzie obs³ugi zdarzenia OnClick drugiego przycisku wywo³ujemy metodê Terminate: PT.Terminate; Przyk³ady Mo na jeszcze dodaæ metodê obs³ugi myszki, np. aby po naciœniêciu jej klawisza wymazywane by³y piksele wokó³ punktu usytuowania kursora myszki. p r e z e n t a c j a... DEL-11(34 z 59)
Wielow¹tkowoœæ Przyk³ady Przyk³ad 2 (synchronizacja za pomoc¹ metod Lock i Unlock) Ten sam przyk³ad, co poprzednio, ale z wykorzystaniem metod blokuj¹cych klasy TCanvas: Lock i Unlock. Za pomoc¹ tych metod uzyskujemy dostêp do powierzchni formatki przez jej blokadê (metoda Synchronize jest wówczas niepotrzebna, co znacznie przyspiesza dzia³anie kodu). Kod metody Execute bêdzie robi³ wszystko po zablokowaniu powierzchni formatki. DEL-11(35 z 59)
Wielow¹tkowoœæ Przyk³ady Przyk³ad 2 (synchronizacja za pomoc¹ metod Lock i Unlock) procedure TPainterThread. Execute; var X, Y : Integer; begin Randomize; repeat try X:=Random(Form1.ClientWidth); Pixels[X,Y]:=clBlue; Y:=Random(Form1.ClientHeight); finally with Form1.Canvas do Unlock begin end Lock; end until Terminated p r e z e n t a c j a... end; DEL-11(36 z 59)
Przyk³ad 3 (priorytety w¹tków) Wielow¹tkowoœæ Przyk³ady Program bêdzie wyœwietla³ piksele w czterech ró nych kolorach (na ekranie bêdzie to widoczne jako wyœwietlanie linii). Tworzymy now¹ wersjê klasy TPainterThread oraz definiujemy konstruktor, którego zadaniem bêdzie zainicjowanie prywatnego pola Color i wywo³anie konstruktora przodka z utworzeniem w¹tku w stanie zawieszenia: DEL-11(37 z 59)
Przyk³ad 3 (priorytety w¹tków) Wielow¹tkowoœæ Przyk³ady type TPainterThread = class (TThread) private Color : Integer; SuspendRequest : Boolean; protected procedure Execute; override; procedure DeleyedSuspend; public constructor Create (Col : TColor); end; DEL-11(38 z 59)
Przyk³ad 3 (priorytety w¹tków) Wielow¹tkowoœæ constructor TPainterThread. Create (Col : TColor); begin Color:=Col; inherited Create (True) end; Przyk³ady Metodê Execute napiszemy tak, by po kolei przechodzi³a przez wszystkie wiersze, ustawiaj¹c kolor ka dego piksela. DEL-11(39 z 59)
Przyk³ad 3 (priorytety w¹tków) procedure TPainterThread. Execute; var X, Y, X1 : Integer; begin X:=0; Y:=0; repeat X1:=X+1; X:=X1 mod 250; Y:=Y+X1 div 250; Y:=Y mod Form1.ClientHeight; Form1.Canvas.Lock; Wielow¹tkowoœæ Przyk³ady DEL-11(40 z 59)
Wielow¹tkowoœæ Przyk³ady Przyk³ad 3 (priorytety w¹tków) try Form1.Canvas.Pixels[X,Y]:=Color; finally Form1.Canvas.Unlock end; if SuspendRequest then begin Suspend; SuspendRequest:=False end until Terminated end; znaczenie tej instrukcji wyjaœniono dalej DEL-11(41 z 59)
Przyk³ad 3 (priorytety w¹tków) Wielow¹tkowoœæ Przyk³ady Na formatce umieszczamy cztery komponenty CheckBox i cztery suwaki (komponenty TrackBar), za pomoc¹ których bêdziemy ustalaæ priorytety w¹tków. Ponadto deklarujemy lokaln¹ tablicê przechowuj¹c¹ cztery obiekty w¹tków: type TForm1 = class (TForm)... private PT : array [1..4] of TPainterThread; end; DEL-11(42 z 59)
Przyk³ad 3 (priorytety w¹tków) Wielow¹tkowoœæ Przyk³ady Tablica PT jest inicjowana w chwili tworzenia formatki (przez metodê obs³ugi zdarzenia OnCreate): procedure TForm1.FormCreate (Sender : TObject); begin PT[1]:=TPainterThread. Create (clred); PT[2]:=TPainterThread. Create (clblue); PT[3]:=TPainterThread. Create (clgreen); PT[4]:=TPainterThread. Create (clblack) end; DEL-11(43 z 59)
Wielow¹tkowoœæ Przyk³ady Przyk³ad 3 (priorytety w¹tków) Dotychczasowy kod tworzy cztery w¹tki jako zawieszone. Uruchamiane s¹ one po zaznaczeniu odpowiedniego pola wyboru (komponentu CheckBox) i ponownie zawieszane po usuniêciu zaznaczenia: procedure TForm1.CheckBoxClick (Sender : TObject); begin if (Sender as TCheckBox).Checked then PT[(Sender as TCheckBox).Tag].Resume else PT[(Sender as TCheckBox).Tag].DeleyedSuspend end; Aby nie pisaæ oddzielnych metod dla ka dego komponentu CheckBox, w³asnoœci Tag ka dego z nich przypisano numer odpowiedniego w¹tku. DEL-11(44 z 59)
Przyk³ad 3 (priorytety w¹tków) Wielow¹tkowoœæ Metoda DeleyedSuspend ustawia pole w¹tku SuspendRequest (typu Boolean) i wartoœæ ta jest sprawdzana na koñcu cyklu wewn¹trz kodu w¹tku (metody Execute) zob. bli ej. Przyk³ady procedure TForm1.RedClick (Sender : TObject); begin if (Sender as TCheckBox).Checked then PT[(Sender as TCheckBox).Tag].Resume else PT[(Sender as TCheckBox).Tag].DeleyedSuspend end; DEL-11(45 z 59)
Przyk³ad 3 (priorytety w¹tków) Wielow¹tkowoœæ Metoda DeleyedSuspend ustawia pole w¹tku SuspendRequest (typu Boolean) i wartoœæ ta jest sprawdzana na koñcu cyklu wewn¹trz kodu w¹tku (metody Execute) zob. bli ej: procedure TPainterThread.DeleyedSuspend; begin SuspendRequest:=True end; Przyk³ady Zastosowana konstrukcja zapewnia, e metoda Suspend jest wywo³ywana tylko wtedy, gdy w¹tek nie blokuje t³a formatki (w przypadku wywo³ania metody Suspend podczas takiej blokady zosta³yby zatrzymane wszystkie w¹tki). DEL-11(46 z 59)
Przyk³ad 3 (priorytety w¹tków) Wielow¹tkowoœæ Przyk³ady W³asnoœci Tag u ywamy te w przypadku suwaków, które ustawiaj¹ aktualny priorytet w¹tków (dziêki temu wystarczy napisaæ jedn¹ metodê obs³ugi zdarzenia OnChage): procedure TForm1.TrackBarChange (Sender : TObject); begin PT[(Sender as TTrackBar).Tag].Priority:= TThreadPriority((Sender as TTrackBar).Position) end; DEL-11(47 z 59)
Przyk³ad 3 (priorytety w¹tków) Wielow¹tkowoœæ Przyk³ady W metodzie tej w celu ustawienia priorytetu wykonujemy konwersjê aktualnego po³o enia suwaka ( Position) na odpowiedni¹ wartoœæ typu wyliczeniowego TThreadPriority, a nastêpnie wykorzystujemy otrzyman¹ wartoœæ do ustawienia priorytetu w³aœciwego w¹tku, zgodnie z w³asnoœci¹ Tag. procedure TForm1.TrackBarChange (Sender : TObject); begin PT[(Sender as TTrackBar).Tag].Priority:= TThreadPriority((Sender as TTrackBar).Position) end; p r e z e n t a c j a... DEL-11(48 z 59)
Wielow¹tkowoœæ Przyk³ady W iemy ju, e istniej¹ dwa typowe rozwi¹zania synchronizacji w¹tku z reszt¹ programu: u ycie metody Synchronize oraz u ycie metod Lock i Unlock, które posiadaj¹ niektóre komponenty VCL. Je eli w¹tek powinien czekaæ a zakoñczy siê inny w¹tek, mo e wywo³aæ metodê WaitFor obiektu odpowiadaj¹cego w¹tkowi, który w³aœnie powinien siê zakoñczyæ. DEL-11(49 z 59)
Wielow¹tkowoœæ Przyk³ady Przyk³ad 4 (oczekiwanie na w¹tek zastosowanie metody WaitFor) Zadaniem programu jest zliczenie liczby wyst¹pieñ czterech podanych znaków w tekœcie komponentu Memo. Znaki podaje siê w polu wejœciowym (komponent Edit). Ka dy z czterech znaków jest szukany przez inny w¹tek utworzony przez w¹tek g³ówny. Dodatkowo ka dy w¹tek wyœwietla wskaÿnik postêpu (komponent ProgressBar), który ilustruje rozmiar tekstu ju przeszukanego. DEL-11(50 z 59)
Wielow¹tkowoœæ Przyk³ad 4 (oczekiwanie na w¹tek zastosowanie metody WaitFor) Przyk³ady pole do wpisania poszukiwanych znaków przycisk rozpoczêcia procesu przycisk do wczytania tekstu (z dysku) wskaÿniki postêpu dla ka dego znaku (ka dy znak jest szukany przez inny w¹tek) pole Memo zawieraj¹ce przeszukiwany tekst DEL-11(51 z 59)
Wielow¹tkowoœæ Przyk³ad 4 (oczekiwanie na w¹tek zastosowanie metody WaitFor) G³ówn¹ klas¹ programu jest klasa TFindThread: type TFindThread = class (TThread) protected liczba przeczytanych znaków Progr : Integer; procedure UpdateProgress; procedure Execute; override; public wynik obliczeñ Found : Integer; przechowanie LookFor : Char; poszukiwanego znaku Progress : TProgressBar; wskaÿnik postêpu end; Przyk³ady DEL-11(52 z 59)
Wielow¹tkowoœæ Przyk³ad 4 (oczekiwanie na w¹tek zastosowanie metody WaitFor) G³ówna metoda w¹tku Execute: procedure TFindThread.Execute; var i, j : Integer; line : string; begin Found:=0; with Form1.Memo1 do for i:=0 to Lines.Count 1 do begin line:=lines[i]; Przyk³ady for j:=1 to Length(line) do if line[j]=lookfor then Inc (Found); Progr:=i+1; Synchronize (UpdateProgress) end end; DEL-11(53 z 59)
Wielow¹tkowoœæ Przyk³ady Przyk³ad 4 (oczekiwanie na w¹tek zastosowanie metody WaitFor) Cztery kopie w¹tku s¹ aktywowane przez w¹tek g³ówny obiekt klasy TMultiFind: type TMultiFind = class (TThread) protected Progr : Integer; procedure UpdateProgress; do wypisania wyników liczbowych procedure Execute; override; procedure Show; public LookFor, Output : string; Progresses : array [1..5] of TProgressBar; end; DEL-11(54 z 59)
Wielow¹tkowoœæ Przyk³ady Przyk³ad 4 (oczekiwanie na w¹tek zastosowanie metody WaitFor) Metoda Execute tej klasy szuka znaków ³añcucha LookFor u ywaj¹c czterech obiektów TFindThread: procedure TMultiFind.Execute; var finders : array [1..4] of TFindThread; i : Integer; begin for i:=1 to 4 do begin finders[i]:=tfindthread.create(true); utworzenie w¹tku finders[i].lookfor:=lookfor[i]; finders[i].progress:=progresses[i+1]; finders[i].resume rozpoczêcie wykonywania end; DEL-11(55 z 59)
Wielow¹tkowoœæ Przyk³ady Przyk³ad 4 (oczekiwanie na w¹tek zastosowanie metody WaitFor) Metoda Execute tej klasy szuka znaków ³añcucha LookFor u ywaj¹c czterech obiektów TFindThread: for i:=1 to 4 do begin finders[i].waitfor; Progr:=i; Synchronize (UpdateProgress) end; Output:= Found: ; for i:=1 to 4 do oczekiwanie na zakoñczenie w¹tku tworzenie ³añcucha z wynikami Output:=Output+Format('%d %s, ', [finders[i].found, LookFor[i]]); Synchronize (Show);... tu trzeba dodaæ usuniêcie w¹tków DEL-11(56 z 59)
Wielow¹tkowoœæ Przyk³ady Przyk³ad 4 (oczekiwanie na w¹tek zastosowanie metody WaitFor) Przycisk Start uruchamia w¹tek, który z kolei natychmiast uruchamia w¹tki drugoplanowe: procedure TForm1.StartClick (Sender : TObject); var i : Integer; begin if Assigned(MainThread) then MainThread.Free; MainThread:=TMultiFind.Create(True); MainThread.Progresses[1]:=ProgressBar1; MainThread.Progresses[2]:=ProgressBar2; MainThread.Progresses[3]:=ProgressBar3; MainThread.Progresses[4]:=ProgressBar4; MainThread.Progresses[5]:=ProgressBar5; DEL-11(57 z 59)
Wielow¹tkowoœæ Przyk³ad 4 (oczekiwanie na w¹tek zastosowanie metody WaitFor) Przycisk Start uruchamia w¹tek, który z kolei natychmiast uruchamia w¹tki drugoplanowe: Przyk³ady MainThread.Progresses[1].Max:=4; for i:=2 to 5 do MainThread.Progresses[i].Max:=Memo1.Lines.Count; for i:=1 to 5 do MainThread.Progresses[i].Position:=0; MainThread.LookFor:=Edit1.Text; MainThread.Resume rozpoczêcie wykonywania g³ównego w¹tku end; DEL-11(58 z 59)
Powodzenia w dokoñczeniu programu we w³asnym zakresie... Szkielet programu, zawieraj¹cy przedstawione elementy, jest do pobrania ze strony www.... i to by by³o na tyle! DEL-11(59 z 59)