Toon posts:

[VC6.0] (milli)seconden delay

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

Verwijderd

Topicstarter
Hallo,

Hoe kan ik een delay routine schrijven (die niet vastloopt zoals mijn huidige routine) om seconden en / of milliseconden te timen in VC6.0?

Momenteel gebruik ik een zelfgeschreven routine die constant de systeemtijd opvraagt tot een bepaald aantal seconden verstreken is. (Het besturingssysteem win98 zegt na een tijd dat mijn programma niet meer reageert. Deze routine werkt voor enkele seconden, maar niet voor milliseconden en voor minuten.)

THX.

  • MisterData
  • Registratie: September 2001
  • Laatst online: 09:53
euhm dat kan met een WM_TIMER message (SetTimer functie moet je es zoeken in de MSDN). Als het preciezer moet moet je es kijken in DirectX ofzo, no doubt dat daar iets dergelijks in zit :)

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

kvdveer

Z.O.Z.

Lees dit eens, en wordt 'verlicht'
http://www.experts-exchan...ual_Basic/Q_20075852.html

Localhost, sweet localhost


Verwijderd

Topicstarter
Ik gebruik Visual C en niet Visual Basic.
En het herprogrammeren van de systeem timer en dan de clock tick interrupt gebruiken lukt niet in VC6.0 (32 bit applicatie.)
Interrupts werken slechts in 16 bit toepassingen zoals een borland C++

[ Voor 29% gewijzigd door Verwijderd op 04-03-2003 21:56 ]


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

kvdveer

Z.O.Z.

In dat topic wordt uitgelegd dat het simpelweg _onmogelijk_ is om betrouwbaar te timen op intervals <1/18 seconden.
Er zijn wel oplossingen. Die zijn niet nauwkeurig, maar ze voldoen wel. De belangrijkste zijn sg. high-resolution multimedia timers. In windows zijn die te vinden in winmm.dll. Hoe windows het doet is 'geheim', maar wine lost het op met een thread die een proces een trap geeft zodra een bepaald aantal instructies is verlopen na de laatste clocktick.

Localhost, sweet localhost


  • Korben
  • Registratie: Januari 2001
  • Laatst online: 14-11-2025

Korben

() => {};

kvdveer schreef op 04 March 2003 @ 22:08:
Hoe windows het doet is 'geheim', maar wine lost het op met een thread die een proces een trap geeft zodra een bepaald aantal instructies is verlopen na de laatste clocktick.
Waarschijnlijk gebruikt Windows de PIT.

[ Voor 34% gewijzigd door Korben op 04-03-2003 22:20 ]

.oisyn: Échte programmeurs haten PHP met een passie. Ben jij soms geen echte programmeur?


  • _js_
  • Registratie: Oktober 2002
  • Laatst online: 13-01 07:19
Gebruik sleep() uit win32api? Dat lijkt me precies wat je zoekt.

  • Zoijar
  • Registratie: September 2001
  • Niet online

Zoijar

Because he doesn't row...

kvdveer schreef op 04 maart 2003 @ 22:08:
Hoe windows het doet is 'geheim'.
Huh? Dat snap ik even niet. Het gaat volgens mij om timings door user applications, het OS zelf kan wel degelijk nauwkeuriger timen. Blijkbaar genereerd windows 18 keer per seconde een "system tick" waar eventueel processen op gescheduled worden etc. Maar de hardware interrupt ticks komen veel vaker binnen bij het OS zelf. Het probleem is dat als je elke hardware tick uitvoerig zou verwerken het systeem erg traag wordt.
Op de pentium wordt er zelfs elke cpu tick een count opgehoogd die je zou kunnen gebruiken, alleen mag daar uiteraard alleen het OS bij :)

Verwijderd

Zoijar schreef op 04 maart 2003 @ 23:27:
Op de pentium wordt er zelfs elke cpu tick een count opgehoogd die je zou kunnen gebruiken, alleen mag daar uiteraard alleen het OS bij :)
Laat het resultaat van 'n QueryPerformanceCounter nou altijd precies het zelfde zijn als het resultaat van die counter. overigens is de RDTSC om die counter op te vragen volgens niet priviledged en mag je 'm gewoon vanuit usermode aanroepen? (niet geheel zeker hier maar wel 90%)

  • .oisyn
  • Registratie: September 2000
  • Laatst online: 22-08 13:19

.oisyn

Moderator Devschuur®

Demotivational Speaker

kvdveer schreef op 04 March 2003 @ 22:08:
In dat topic wordt uitgelegd dat het simpelweg _onmogelijk_ is om betrouwbaar te timen op intervals <1/18 seconden.
Er zijn wel oplossingen. Die zijn niet nauwkeurig, maar ze voldoen wel. De belangrijkste zijn sg. high-resolution multimedia timers. In windows zijn die te vinden in winmm.dll. Hoe windows het doet is 'geheim', maar wine lost het op met een thread die een proces een trap geeft zodra een bepaald aantal instructies is verlopen na de laatste clocktick.


ten eerste is die topic echt onzin, ze hebben er duidelijk geen verstand van. Leuk dat de VB timer 'slechts' 1/18e seconde precisie heeft, maar dat heeft verder weinig met windows te maken, meer met VB zelf

QueryPerformanceCounter () is iig precieser dan 1 ms, zeker op winNT kernels. Verder kun je ook nog ver komen met GetThreadTimes (), wat verschillende tijden van een bepaalde thread geeft. Ook deze tijden zijn heel erg precies.

Sleep () is kwa milliseconde precisie niet betrouwbaar, omdat als een thread wakker wordt hij nog niet direct aan de beurt komt, aangezien de thread die op dat moment bezig is de rest van z'n timeslice gewoon afmaakt. De prioriteit van de huidige thread omhoog zetten werkt echter wel.

Maar goed, volgens mij gaat het hier niet om precisie, maar meer om het feit dat ie z'n app wil delayen zonder dat de message loop gestopt wordt. Dan kan er idd gebruik worden gemaakt van de WM_TIMER message (zie SetTimer ())

Een andere oplossing is een waitable timer maken, en dan wachten tot die timer verstreken is, maar wel ondertussen window messages afvangen:

C++:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
bool wait (DWORD msecs)
{
    struct ScopedHandle   // helper struct for closing the handle
    {
        HANDLE handle;
        ScopedHandle (HANDLE pHandle) : handle (pHandle) { }
        ~ScopedHandle () { CloseHandle (handle); }
        operator HANDLE () { return handle; }
    };

    ScopedHandle timer = CreateWaitableTimer (NULL, TRUE, NULL);
    

    LARGE_INTEGER waitTime;

    // time in 100 nanosecond intervals, relative time:
    waitTime.QuadPart = (__int64)msecs * -10000;
    SetWaitableTimer (timer, &waitTime, 0, NULL, NULL, FALSE);


    while (true)
    {
        DWORD r = MsgWaitForMultipleObjects (1, &timer, FALSE, INFINITE, QS_ALLINPUT);
        if (r == WAIT_OBJECT_0 + 1)    // message in queue
        {
            MSG msg;
            if (!GetMessage (&msg, NULL, 0, 0))  // quit message?
                return false;
            TranslateMessage (&msg);
            DispatchMessage (&msg);
        }
        else
            return true;
    }
}


retourneert true als er gewacht is, en false als de tijd nog niet verstreken was maar er een quit message was binnen gekomen

niet getest enzo :)

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


Verwijderd

Topicstarter
Allemaal bedankt voor de reacties.
Ik heb de MSDN nog eens geraadpleegd omdat ik hier telkens clocktick hoorde vallen.
Het volgend is uit de bus gekomen met de functie GetClockTick:
void sdelay(double seconden)
{
double delaytime=seconden*1000;
DWORD delay=static_cast <DWORD> (delaytime);
DWORD systemtimer=GetTickCount();
delay+=systemtimer;
while(systemtimer<delay)
systemtimer=GetTickCount();
}
Volgens msdn gettickcount slechts een resolutie van 55ms met een OS als win98.
Voor mijn toepassing is dit nauwkeurig genoeg.

Nogmaals dank voor de handige tips.
THX. BDC

[edit]:
Aan de MODS: Voor mij mag er een slotje op. Ik heb een antwoord op mijn vraag. _/-\o_

[ Voor 9% gewijzigd door Verwijderd op 05-03-2003 20:03 ]


  • .oisyn
  • Registratie: September 2000
  • Laatst online: 22-08 13:19

.oisyn

Moderator Devschuur®

Demotivational Speaker

Verwijderd schreef op 05 maart 2003 @ 19:54:
Allemaal bedankt voor de reacties.
Ik heb de MSDN nog eens geraadpleegd omdat ik hier telkens clocktick hoorde vallen.
Het volgend is uit de bus gekomen met de functie GetClockTick:
void sdelay(double seconden)
{
double delaytime=seconden*1000;
DWORD delay=static_cast <DWORD> (delaytime);
DWORD systemtimer=GetTickCount();
delay+=systemtimer;
while(systemtimer<delay)
systemtimer=GetTickCount();
}
Volgens msdn gettickcount slechts een resolutie van 55ms met een OS als win98.
Voor mijn toepassing is dit nauwkeurig genoeg.
nadeel van deze methode is dat je app 100% cpu vreet, en je zit nog steeds met dat probleem dat ie niet reageert als je een lange tijd wacht
Aan de MODS: Voor mij mag er een slotje op. Ik heb een antwoord op mijn vraag. _/-\o_
dat kan niemand meer reageren, da's niet handig[/html]

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


Verwijderd

Congrats je hebt een versie van sleep() gemaakt. maar dan een die cpu tijd vreet..
Pagina: 1