[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