[elektro] idoosztasi strategia

Info info at kiralyelektronika.hu
Sat Jul 30 01:26:06 CEST 2011


>Ez a gombhoz rendelt eseménykezelő hozza létre a thread-et.
>Gondolom a MY itt egy olyan memória területet jelent ami a thread
>példány működéséhez szükséges adatokat tartalmazza. De hogyan lehet ez
>lokális változója egy eseménykezelőnek, hiszen a thread sok másodperccel
>az után is fut, hogy az eseménykezelő már kilépett és nyilván
>felszabadította a stacket.

Jujj. No, nézzük sorban:

> procedure TForm1.Button1Click(Sender: TObject);
> var
>     MY : TTesztThread ;

Jól tudod, a veremben csinál egy mutatónak helyet.

> begin
>    MY := TTesztThread.Create(True) ;

A TObject.Create függvényig lefut minden öröklött Create fgv, és a
foglalás itt történik, a címét visszaadja az objektumnak.

Beteszi az objektum címét a veremben foglalt mutatóba, hogy hívni
tudja a metódusokat a VMT-ből. 

>    MY.Honnan := 'D:\teszt.vmi' ;
>    MY.Hova := 'C:\teszt.vmi' ;
>    MY.Resume ;

A tárolt mutató felhasználásával az objektum részeit eléred, írsz
bele, futtatod a Resume fgv-t.

> end ;

Naszóval, innentől sehol nem fogod tudni elérni ezt az objektumot.
Tulajdonképpen eldobtad a címét, magárahagytad.
Saját magának kell felszabadulni, kilépni a memóriából majd valamikor,
stb.

Amikor újrahívod ezt a ButtonClicket akkor egy újabb objektum jön
létre és fut.

A baj ezzel a megoldással az, hogy amikor bezárod a processt akkor
leállnak a threadok ha a process leállításakor nem akarod megváratni.
Azaz mondjuk félbeszakad a végrehajtás. A processz a szálak csoportja.

Javaslom soha ne dobd el így az objektum címét és kilépéskor akár
OnClose-ban akár finalizationban érd el a száladat és szólj neki, hogy
söprés kifele a memből mert a rendszer/user kirúgja hamarosan.
Az elegáns megoldás az, ha az OnCloseQuery-be teszed és addig nem
térsz vissza amíg le nem álltak a szálak. Mondjuk felugró ablak "kérem
várjon" vagy valami.

Még két dolog a szálakhoz delfiből: az egyik, hogy csak az execute()
maga a szál, az összes többi objektum-elem nem tartozik hozzá.
Induláskor ha createsuspended false akkor azonnal elindul és ha
lokális változókat nem inicializálta a rendszer hibásan fogsz futni. A
fenti példában ezért volt true a suspended, majd beállítótta a loc
paramokat majd resume/folytatás. Így létrehozás után nem olvassa a
hülyeséget egyből hanem vár.
A Suspend/resume nem tudja hol áll a szál. Éppen egy másik belőle
hívott fgv közepén is megállhatsz ha suspendet hívsz.
A terminate fgv pedig nem csinál az égvilágon semmit, csak a Treminate
változónak ad true értéket.

A másik a vizualizálás: sok időt elvesz és ami bonyivá teszi: a win
alap objektumaira van ráhúzva.  Tehát pl. a TCombobox egy sima Edit
mező, natúr üzenget az objektumod neki, hogy most így jelenjen meg
most úgy, stb. No szóval oda akarok kilukadni, hogy a többszálúság
ugyanazt a fgv-t hívhatja/üzenetet küldheti többször, ezért kitalálták
a Synchronize() metódust amit a szálból kifelé híváskor kell
használnod. Tehát az executen-belül, és mégpontosabban akkor ha
vizuális dolgot hívsz, VCL komponenst. Ez a synchronize azt csinálja a
háttérben, hogy létrehoz egy eventet, beteszi a száladat a
waitforsingleobject()-re, talán még lockolja is aztán meghívja a
kívánt függvényt, majdha visszatért a hívott fgv setevent és
folytatódik a szál futása.

Az Application objektum meg ott bugzik egy kicsit a szálakkal, hogyha
a szálban vársz egy értékre amit ugye VCL-ből kapsz mondjuk checkboxra
vársz, aztán az alkalmazás is vár a szálra na akkor várhatnak az idők
végezetéig :) ugyanis a win alap getmessage/processmessage-ja az
applicationba fut és ő osztja szét a formoknak. Namost ez egy szál,
meg Te csinálsz másikat és a kimenete is meg a bemenete is ugyanúgy
állni fog. Nemtom érted-e. Példával:

Ha a száladra akarsz várni elegánsan akkor időnként kell
app.processmsg valahogy így:

 while WaitforSingleObject(hEvent, 20) <> wm_Timeout do
    Application.ProcessMessages.

Így az alkalmazás alap szála időnként lekezel 1-1db win üzenetet,
talán nem veszlik el az egérklikkelés a sorból és meg tudod várni az
indított szálból küldött eventet.

Mondjuk ide meg már érdemesebb pipet vagy wm_userxxx üziket
küldözgetni.



More information about the Elektro mailing list