Sign in Join
Wiki copytemporary

Multithreaded Application Tutorial/sk: what changed

Revision 1 to 2. Removed lines have a minus sign; added lines have a plus sign.

OldNewLine
11## Prehľad
22
33Táto stránka vám pomôže s pochopením vývoja a debugovania viacvláknových programov s použitím Free Pascale a Lazarusa.
44
55Viacvláknový program je program, ktorý vytvorí dve a viacero vlákien pre vykonanie svojej práce v rovnaký čas.
66
77Jedno z vlákien je hlavné. Hlavné vlákno je vlákno vytvorené operačným systémom pri štarte programu. Hlavné vlákno **musí** byt jediné, ktoŕe obnovuje komponenty, ktoré sú spojené s uživateľom (v opačnom prípade môže program uschnúť).
88
99Hlavná myšlienka viacvláknového programovania spočíva v tom, že zatiaľ čo sa bude vykonávať vedľajšia činnosť ktorá by blokovoala, tak hlavné prostredie pre prácu s uživateľom môže fungovať ďalej ako hlavné vlákno.
1010
1111Ďalšie použitie vlákien je ak chceme mať viacej raktívnu aplikáciu. Ak napr. vytvoríte aplikáciu v ktorej keď sa stlačí gombík tak sa spracuje veľa dát (spracovanie trvá..) tak by sa v normálnom prípade mohlo zdať že sa program "zasekol", čo nieje zrovna chcená vlastnosť. Ak by spracovanie bežalo vo vedlajšom vlákne, aplikácia zostáva reaktívnou ako keby sa nič nedialo. V takýchto prípadoch je dobrý zvyk povoliť štart len jedného vedlajšieho vlákna. (V opačnom prípade by mohli nastať nežiadúce situácie keď by užívateľ naštartoval viacej vlákien, ktoŕe by robili to isté)
1212
1313Ďalšie možné využitie je pri sieťovom servery, kde sa musí obsluhovať naraz viac spojení.
1414
1515## Trieda TThread
1616
1717Najjednoduchší spôsob na vytvorenie viacvláknovej aplikácie je trieda TThread.
1818
1919Táto trieda umožnuje vytvorenie dodatočného vlákna (popri hlavnom) jednoduchým spôsobom.
2020
2121V štandardných prípadoch musíte overridnúť 2 metódy: konštruktor Create a procedúru Execute.
2222
2323V konštruktore pripravíte vlákno na chod. Nastavíte základné hodnoty premenným alebo vlastnostiam podľa potreby. Nadriadený konštruktor TThreadu vyžaduje parameter nazívaný Suspended. Ako ste možno uhádli, byť Suspended = True zabráni vláknu aby sa spustilo automaticky po vytvorení. Ak Suspended = False, vlákno sa spustí hned po vytvorení. Ak ste vlákno vytvorili suspended, musíte ho "spustit" pomocou Resume.
2424
2525Od verzie FPC 2.0.1 a vyžšej má TThread.Create aj implicitný parameter Stack Size. Od teraz môžete meniť veľkosť stacku pre jednotlivé vlákna. Dobrým príkladom využitia tohto parametra je, ak vo vlákne robíte hlboké rekurzie. Ak nešpecifikujete parameter Stack Size, tak je vybraná štandardná veľkosť v závislosti od operačného systému.
2626
2727V overridnutej metóde Execute napíšete kôd ktorý sa má počas behu vlákna vykonať.
2828
2929Trieda TThread ma jednu veľmi dôležitú vlastnost: Terminated : boolean;
3030
3131Ak má vlákno cyklus (čo je obvyklé), musí sa v cykle kontrolovať, či je Terminated true (štandardne je false). Takže je nutné sa v každom prechode v cykle pozrieť, či je Terminated True, a ak áno, musí sa metóda Execute ukončiť tak rýchlo ako je to možne. (netreba zabúdať na uvolnenie pamäťe ak bola nejaka naalokovaná)
3232
3333Zapamätajte si že vlasnosť Terminate nerobí sama o sebe nič. Je nutné naprogramovať metódu Execute tak, aby ju brala do úvahy.
3434
3535Ako bolo vysvetlené, nieje možné aby sa z vedlajšieho vlákna nejakým spôsobom ovlivnovalo grafické prostredie a komponenty. Aby sme niečo uživateľovi ukázali, musíme to spraviť cez hlavné vlákno. Z tohto dôvodu existuje metóda Synchronize. Synchronize vyžaduje metódu (bez argumentov) ako argument. Keď svoju metódu zavoláte cez Synchronize(@MojaMetoda), vlákno bude "zapauznuté" a kód v MojaMetoda sa vykoná v hlavnom vlákne, po čom sa následne uvoľní vedlajšie vlákno.
3636
3737Ďalšou dôležitou vlastnosťou je FreeOnTerminate. Ak je táto vlastnosť true, tak je objekt TThreadu automaticky uvoľnený z pamäti po dokončení vykonávania (metódy .Execute). V opačnom prípade musí aplikácia uvoľniť objekt sama.
3838
3939Príklad:
4040
4141` Type`\
4242`   TMyThread = class(TThread)`\
4343`   private`\
4444`     fStatusText : string;`\
4545`     procedure ShowStatus;`\
4646`   public`\
4747`     Constructor Create(Suspended : boolean); override;`\
4848`     procedure Execute; override;`\
4949`   end;`
5050
5151` constructor TMyThread.Create(Suspended : boolean);`\
5252` begin`\
5353`   inherited Create(Suspended);`\
5454`   FreeOnTerminate := True;`\
5555` end;`
5656
5757` procedure TMyThread.ShowStatus;`\
5858` begin`\
5959`   Form1.Caption := fStatusText;`\
6060` end;`\
61-\
61+
6262` procedure TMyThread.Execute;`\
6363` var`\
6464`   newStatus : string;`\
6565` begin`\
6666`   fStatusText := 'Starting...';`\
6767`   Synchronize(Showstatus);`\
6868`   fStatusText := 'Running...';`\
6969`   while (not Terminated) and ([vaša podmienka]) do`\
7070`     begin`\
7171`       ...`\
7272`       [sem vložte kód hlavného cyklu]`\
7373`       ...`\
7474`       if NewStatus <> fStatus then`\
7575`         begin`\
7676`           fStatusText = newStatus;`\
7777`           Synchronize(Showstatus);`\
7878`         end;`\
7979`     end;`\
8080` end;`
8181
8282On the application,
8383
8484` var`\
8585`   MyThread : TMyThread;`\
8686` begin`\
8787`   MyThread := TMyThread.Create(True); // Takto sa vlákno vytvorí "suspended"`\
8888`   ...`\
8989`   [sem vložte inicializačný kód]`\
9090`   ...`\
9191`   MyThread.Resume;`\
9292` end;`
9393
9494## Dôležité veci na ktoré je treba dávať pozor
9595
9696Ak vo Windowse používate vlákna a máte zapnutú kontrolu pretečenia stacku (-Ct), vlákno sa nevykoná. Z dôvodu implementácie kontroly stacku sa po TThread.Create vlákno nevykoná ale vyvolá vínimku. Táto vínimka NIEJE vyvolaná v hlavnom vlákne, čo znamená že nieje zaznamenaná. Správny spôsob vytvárania vlákien aby ste výnimky zaznamenali je:
9797
9898`    MyThread:=TThread.Create(False);`\
9999`    if Assigned(MyThread.FatalException) then`\
100100`      raise MyThread.FatalException;`
101101
102102Tento kód zaruči, že ak sa pri vytváraní vlákna vyvolá vínimka, bude vyvolaná aj v hlavnom vlákne. Jeviný spôsob ako sa vo Windowse vyhnút tejto chybe je nepoužívať kontrolu stacku (prepínač -Ct). Kontrola stacku je štandardne vypnutá.
103103
104104## Unity podrebné na viacvláknové programovanie
105105
106106Vo windowse nieje treba žiadnych špeciálnych unít. V linuxe je treba použiť unitu cthreads, ktorá *musí* byť prvá v hlavnom programe!
107107
108108Váš program bude vizerať takto:
109109
110110` program MyMultiThreadedProgram;`\
111111` {$H+}`\
112112` uses`\
113113` {$ifdef linux}`\
114114`   cthreads,`\
115115` {$endif}`\
116116`   Interfaces, // this includes the LCL widgetset`\
117117`   Forms`\
118118`   { add your units here },`
119119
120120## Podpora SMP
121121
122122------------------------------------------------------------------------
123123
124124Dobrá správa je, že pokiaľ vaša aplikácia beži na viacerých vláknach má automaticky podporu SMP!
125125
126126## Debugovanie viacvláknových programov v Lazaruse
127127
128128Debugovanie v lazaruse ešte nieje úplne funkčné. Ale ak sa pokúsite debugovat viacvláknovú aplikáciu v Linuxe uschne vám X server.
129129
130130Nieje známe riešenie ale jeden dočasný spôsob je:
131131
132132Vytvorenie novej inštancie X pomocou:
133133
134134` X :1 &`
135135
136136Naštartuje sa nový X a keď prepnete do ďalšej plochy (stlačením CTRL+ALT+F7) budete môcť ísť späť do novej grafickej plochy stlačením CTRL+ALT+F8 (ak skratky nefungujú skúste CTRL+ALT+F2... to fungovalo na Slackware).
137137
138138Potom môžete ak chcete vytvoriť nové sedenie na X:
139139
140140` gnome-session --display=:1 &`
141141
142142Potom v Lazaruse v nastavení projektu / run parameters zašktnite "Use display" a vložte :1.
143143
144144Teraz sa aplikácia spustí na X serveri č. 2 a vy ju môžete debugovať zo servera 1.
145145
146146Toto bolo otestované s Free Pascal 2.0 a Lazarus 0.9.10 na Windowse a Linuxe
147147
148148---
149149*From the Free Pascal wiki, page "Multithreaded Application Tutorial/sk", as it stood on 2006-05-28 after a change by Msmat, out of the wiki's dump of 2024-05-26. Copyright stays with the author who wrote it, according to the old wiki's [[Licensing]] page. If you have concerns about this material, [message the admin](/wiki-contact).*

Back to history