1

I need to find a way to trigger the execution of a C++ function at the exact millisecond periods.

I need to play a loop and run a function every 40 ms or less. But for the simplicity let's stay with 40 ms. I tried to put a Sleep(40) but the method is triggered not at exact point of time.

I am just wondering if there is another way for synchronizing actions then having a Sleep() in a endless while loop.

I tried even to play a loop at max speed (CPU went to 20%) and measuring the system time difference. Then triggering the action when 40 ms has passed.

In both cases I am experiencing delays but the worst case is that the delays are always different.

The loop is running in the thread.

I tried to give bigger priority to the thread but without success.

Additional Information

The Server is running on Windows 7 Operating System.

Patrik
  • 1,286
  • 1
  • 31
  • 64
  • This has already been answered at [Q & A ][1]. [1]: http://stackoverflow.com/questions/4184468/sleep-for-milliseconds – goldcode Nov 10 '13 at 21:37
  • Can you give a little bit more information about the environment (operating system, hardware etc) ? and the exact reason you need something that is executed every 40ms ? – tigrou Nov 10 '13 at 21:37
  • I need to play a movie in the XBMC player that needs to send data to the server at specific frame rate. So 25 fps = 40 ms each frame. The server needs to send some values to some hardware at specific times and needs to be in sync. Everything runs on Windows OS. So unfortunately no real time OS. – Patrik Nov 10 '13 at 21:42
  • Then you already know the answer, you are doing it wrong. A reliable frame rate is only required in the program that displays the video. It is entirely immaterial what kind of random delays are experienced upstream from that, only buffering is required. – Hans Passant Nov 10 '13 at 21:50

1 Answers1

1

You can track the time using a function such as timeGetTime:

void main()
{
    unsigned int last_call_time = timeGetTime();

    while(true)
    {
        do_something_else();

        unsigned int now_time = timeGetTime();
        if(now_time > (last_call_time + 40))
        {
            call_time_critical_function();
            last_call_time = timeGetTime();//last time is re initialized
        }
    }
}

timeGetTime is standard windows function that tracks the time in milliseconds. If the function is not precise enough you would have to use something that can track nanoseconds like QueryPerformanceCounter and there a lots of examples on the web on how to use this function.

Raxvan
  • 6,257
  • 2
  • 25
  • 46
  • I would recommend to put some minimal `usleep()` or other timed blocking function inside the while loop, instead of doing such busy (tight CPU consuming) wait. – πάντα ῥεῖ Nov 10 '13 at 21:42
  • This doesn't account for the length of time it takes to do the critical function. If that function varies in duration you won't get the right interval. – Jerry Jeremiah Nov 10 '13 at 21:42
  • I don't know a lot about multi-media programming on Windows, but is a polling loop the right choice?! – usr Nov 10 '13 at 21:43
  • Actually the thing to do is sleep until the next callback time (e.g. usleep(max(0, last_call_time+40-timeGetTime())); – Jeremy Friesner Nov 10 '13 at 21:43
  • Exactly. Regardless of the way I am trying the sleep lasts 40ms 41ms 42 43ms... and you never know how much. – Patrik Nov 10 '13 at 21:44
  • @Jerry Jeremiah yes, it is a simple example to illustrate the usage of timeGetTime(). – Raxvan Nov 10 '13 at 21:44
  • @Patrik Sleep function (i'm not sure of usleep) will put the current thread out of CPU and timing will be really hard since it can take time for the thread to start execution again. If timing is critical you should use QueryPerformanceCounter inside a loop and keep the track of the time manually. – Raxvan Nov 10 '13 at 21:49