[elektro] idoosztasi strategia
Nemeth Tibor
nemeth.tibor798 at t-online.hu
Fri Jul 29 18:05:31 CEST 2011
Hali!
Évtizedek óta írok adatgyűjtő és vezérlő programokat de nem igazán érzem
hatékonynak ahogy csinálom. Ezzel kapcsolatban kérem tanácsotokat.
Régen DOS alatt, viszonylag hardverközeli megoldások is szóba jöttek,
akár hardver interrupt kezelés is. Amióta rákényszerültem a windows-ra
ezzel már nem kísérletezem. A példák, mivel Delphiben nyomulok, pascal
szintaxissal lesznek, de gondolom, nem ez a lényeg.
Nézzük mi is a gondom: A windows arra van kitalálva, hogy a juzer
kattintgat és ennek hatására lefutnak eljárások, esemény kezelők. Ezek
rövid lefutású részprogramok. Ezzel szemben egy mérőprogram akár napokig
is futhat, noha lehetséges, hogy egy hét alatt lesz annyi dolga a
CPU-nak mint mondjuk egy nagyobb kép elforgatásával, tehát a feladat
nagyon hosszú és nagyon híg.
A tennivaló tehát nem sok, ugyanakkor gyakran külső feltételekre kell
várakozni. Ha ezt így kezelem le:
while feltetel do;
akkor teljesen feleslegesen agyonterhelem a gépet, fölösleges
másodpercenként húszmilliószor megnézni. Terhelés szempontjából jó megoldás
while feltétel do sleep(200);
Így csak ötször nézi meg, ez a feladattól függően elég is lehet, közben
meg csinálhat mást. Ezzel csak egy baj van, a feladat folytatódik, lesz
még benne száz ilyen és az eseménykezelő amivel elindítottam (pl:gombra
kattintás) soha nem ér véget és ezért ha közben valami juzer kívánság
mégis adódna, nem tudom kiszolgálni. Felhasználói oldalról úgy néz ki,
mintha kifagyott volna a program, nem reagál egérre, gombra.
Ezért programjaimat timer által generált eseményekkel vezérlem. Ezt már
évek óta csinálom, működik is csak nagyon kényelmetlen ha a feladat
bonyolódik. Úgy képzeljétek el, hogy a feladat meg van írva, tele
ciklusokkal elágazásokkal és ahol a fenti példa szerint várakozási van a
sleep helyett a program kilép a timer eseményből de gondoskodni kell
róla, hogy az újabb timer eseményre a kihagyott sleep után folytassa.
Közben, a ki és belépés között a közben fellépő események
kiszolgálhatók. Globális változókon keresztül módosíthatják a timer
alatt futó főtevékenység menetét is.
No ezért most a timer rutin kb. így néz ki:
var fazis:integer;
procedure TForm1.Timer1Timer(Sender: TObject);
begin
amitmindigkell_eleje;{ebben nincs hosszú várakozás feltételekre}
case fazis of
1:begin valamitcsinal1; if feltetel1 then inc(fazis) end;
2:begin valamitcsinal2; if feltetel2 then fazis:=4 else inc(fazis) end;
3:begin valamitcsinal3; if feltetel3 then fazis:=9 end;
4:begin valamitcsinal4; inc(fazis) end;
5:begin valamitcsinal5; if feltetel5 then inc(fazis) end;
..............
end{case fazis};
amitmindigkell_vege;{ebben nincs hosszú várakozás feltételekre}
end{Timer};
Ez a példa egyszerűnek tűnik, de a valóságban gyakran többszintű.
A valamitcsinalx-ekben esetleg hasonló programrészek lehetnek, tehát nem
várakozunk, hanem kilépünk.
Egymásba ágyazott ciklusokat kell félbehagyni és kilépni, ehhez további
globális változókban tárolt adatok kellenek és hirtelen követhetetlenné
válik a dolog.
Ti hogyan csináljátok?
Lehet, hogy meg kellene tanulnom thread-eket Ha ez a megoldás és valaki
megdobna egy működő példával megköszönném és persze bármi más jó tanácsot.
Üdv.
Németh Tibor
More information about the Elektro
mailing list