[Delphi] Threads realtime dingen laten uitvoeren

Pagina: 1
Acties:
  • 119 views sinds 30-01-2008
  • Reageer

  • Krooswijk.com
  • Registratie: Mei 2000
  • Laatst online: 17-08-2024
Hallo hallo, ik ben nu een programma aan 't maken die om een bepaalde tijd tests uit moet gaan voeren. Hiervoor creeer ik tijdens het opstarten van mijn mainform een Thread. Deze thread blijft op de achtergrond in een (in principe) oneindige while lus kijken wanneer de huidige tijd gelijk is aan een van de 'testtijden' is het tijd dan wordt de lus onderbroken en wordt de test uitgevoerd, daarna wordt de 'execute' van de thread weer aangeroepen en gaat er weer gewacht worden tot het tijd is voor een volgende test.
Mijn vraag luidt nu als volgt:
Is dit een goede manier? Volgens mij worden sommige testtijden namelijk wel eens overgeslagen (wat ik mij overigens kan voorstellen), hoe kan ik dit oplossen? Of heeft iemand een andere suggestie. De thread is nodig, omdat de gebruiker in de tussentijd andere dingen met het programma moet kunnen doen.

  • jopiek
  • Registratie: September 2000
  • Laatst online: 21-08 19:56

jopiek

Tja... 'ns ff denken.

Op donderdag 13 september 2001 05:14 schreef Da Snake het volgende:
Hallo hallo, ik ben nu een programma aan 't maken die om een bepaalde tijd tests uit moet gaan voeren. Hiervoor creeer ik tijdens het opstarten van mijn mainform een Thread. Deze thread blijft op de achtergrond in een (in principe) oneindige while lus kijken wanneer de huidige tijd gelijk is aan een van de 'testtijden' is het tijd dan wordt de lus onderbroken en wordt de test uitgevoerd, daarna wordt de 'execute' van de thread weer aangeroepen en gaat er weer gewacht worden tot het tijd is voor een volgende test.
Mijn vraag luidt nu als volgt:
Is dit een goede manier? Volgens mij worden sommige testtijden namelijk wel eens overgeslagen (wat ik mij overigens kan voorstellen), hoe kan ik dit oplossen? Of heeft iemand een andere suggestie. De thread is nodig, omdat de gebruiker in de tussentijd andere dingen met het programma moet kunnen doen.
sommige cycles worden inderdaad overgeslagen als een andere thread met hogere prioriteit langskomt!
Zie ook het threadvoorbeeld in de demodir trouwens

Cogito Ergo Credo


  • ta_chi79
  • Registratie: Juli 2001
  • Laatst online: 21-09 22:43
Kan het niet zijn dat de test langer duurt dan de interval van de aanroepende thread?

Probeer het eens op deze manier:
while true do begin
if Now >= fTargetTime and not fBusy then begin
SetBusyTrue;
myThread := TTestThread.Create(...);
myThread.OnTerminate := SetBusyFalse;
myThread.Resume;
end else
Sleep(60000);
end;

  • kvdveer
  • Registratie: November 2000
  • Laatst online: 06-11-2025

kvdveer

Z.O.Z.

Deze techniek heet busy-waiting. Algemeen bekend als een zeer slechte techniek. Deze ver*** namelijk je multitreading en multiprocessing voor andere apps. Bovendien gebruikt 'ie veel te veel processorcycles, en dat is slecht voor je }:O
Probeer eens wat met een timer
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
timer:TTimer;
TestTimes:array of TDateTime;
nextTime:integer // het volgende moment van actie.


procedure onTimer
begin
  nexttime := volgende tijd...;
  timer.interval := (nextTime - now()) * 24 * 60 * 60 * 1000;
  Timer.reset;
  timer.enable;
  runTest
end;

bovenstaande code moet je nog wel even vertalen naar OPascal. Maar dat moet wel lukken... Veel plezier er mee.

Localhost, sweet localhost


  • Krooswijk.com
  • Registratie: Mei 2000
  • Laatst online: 17-08-2024
Op donderdag 13 september 2001 07:56 schreef jopiek het volgende:

[..]
sommige cycles worden inderdaad overgeslagen als een andere thread met hogere prioriteit langskomt!
Zie ook het threadvoorbeeld in de demodir trouwens
Kan ik mijn thread dan een hogere prioriteit geven zonder dat dit het hoofdprogramma aantast?
Op donderdag 13 september 2001 08:26 schreef ta_chi79 het volgende:
Kan het niet zijn dat de test langer duurt dan de interval van de aanroepende thread?
code:
1
2
3
4
Probeer het eens op deze manier:
while true do begin
....
end;
Nee in principe kan dat niet, het programma naar alle waarschijnlijkheid drie keer per dag draaien ofzo, maar wel bedankt...
Maaaarrrrr, misschien doe ik er toch nog iets mee.
Op donderdag 13 september 2001 08:32 schreef kvdveer het volgende:
Deze techniek heet busy-waiting. Algemeen bekend als een zeer slechte techniek. Deze ver*** namelijk je multitreading en multiprocessing voor andere apps. Bovendien gebruikt 'ie veel te veel processorcycles, en dat is slecht voor je }:O
Probeer eens wat met een timer

...

bovenstaande code moet je nog wel even vertalen naar OPascal. Maar dat moet wel lukken... Veel plezier er mee.
Ik heb het met een timer draaiende gehad, maar het probleem is dan dat ik niet op een gezette tijd aan de slag kan, maar alleen na een bepaalde periode na het aflopen van een vorige test. De starttijd voor de volgende test is dan variabel en dat moet niet.

  • Creepy
  • Registratie: Juni 2001
  • Laatst online: 16:55

Creepy

Tactical Espionage Splatterer

Een timer gebruiken.. en IN die timer de tijd checken.. als de goede tijd is aangebroken, dan je thread aanroepen (of gewoon een procedure, als het hoofdgedeelte niks hoeft te doen als de thread runt.)

Bijv 1 keer per seconden checken op de tijd. en als de huidige tijd gelijk is aan, of groter dan aan de ingesteltde tijd dan dus wat gaan doen. Ook dat groter dan gebruiken dus, aangezien windows een Multitasking OS is, en geen REALTIME os.. dus je weet nooit zeker dat je proggie de processor kan gebruiken op de ingestelde tijd.

En in dat voorbeeld hierboven wat zo mooi busy waiting genoemd werd... als je SLEEP gebruikt zet je dus echt je programma aan de kant voor de tijd die in de sleep staat.. Dan gebruikt je proggie dus ook de processor helemaal niet. De schedular van windows (die bepaalt wanneer welk prog de processor mag gebruiken) geeft je prog dan weer tijd na die sleep..

"I had a problem, I solved it with regular expressions. Now I have two problems". That's shows a lack of appreciation for regular expressions: "I know have _star_ problems" --Kevlin Henney


  • kvdveer
  • Registratie: November 2000
  • Laatst online: 06-11-2025

kvdveer

Z.O.Z.

Op donderdag 13 september 2001 08:49 schreef Da Snake het volgende:
Ik heb het met een timer draaiende gehad, maar het probleem is dan dat ik niet op een gezette tijd aan de slag kan, maar alleen na een bepaalde periode na het aflopen van een vorige test. De starttijd voor de volgende test is dan variabel en dat moet niet.
Moet je even mijn code lezen. Deze gaat op een vaste tijd aan de slag, namelijk na x miliseconden na nu.
stel nu = 15:10:12.928 en jij wilt om 15:10:13.500 wat uitvoeren, dan zet je de interval op 572ms. Op deze manier heb je toch een redelijk nauwkeurige benadering. Als je code goed in elkaar zit, dan mis je (gegarandeerd) geen events. Alle events worden (bij normale processor belasting) binnen 10 miliseconden na de door jou gewenste tijd uitgevoerd.


Als het nauwkeuriger moet (binnen de ms) dan moet je nog weer andere technieken nemen, maar dat wordt zeer complex.

Localhost, sweet localhost


Verwijderd

Een timer is meestal de beste oplossing: dit component is ervoor gemaakt. Anders kun je de sleep()-functie gebruiken. Beide oplossingen geven aan het OS aan dat 'hun' thread voorlopig geen processortijd nodig heeft, wat goed is voor je systeemperformance.
Het hangt wel een beetje af van het interval en de gewenst nauwkeurigheid. Als je 1x per 5 minuten de buitentemperatuur wilt meten werkt een timer prima: een halve seconde meer of minder boeit dan niet. Als je een signaal wilt samplen op basis van de RTC heb je een ander probleem (meerdere, eigenlijk...).
Pagina: 1