Click to See Complete Forum and Search --> : Sleep vs. Timer Event (VC++)
tnarol
May 22nd, 2006, 08:35 AM
Hi,
I need a thread to have things done at constant intervals of time.
Basically it would be :
for( ; ; )
{
Wait for time interval to be elapsed
Do things
}
My question is : what is the best way to wait ?
Is it better to call Sleep(TIME_INTERVAL) ?
or to program a timer that will set an event that I can wait using WaitForSingleObject ?
or something else ?
Thanks
tnarol
May 22nd, 2006, 09:26 AM
Just read the following page :
http://www.flounder.com/badprogram.htm#Sleep
It seems this guy doesn't like programs using Sleep because you can't predict the waiting time accurately. But since I don't need more than 20ms precision I'm not fully convinced this is not suitable for me.
ahoodin
May 22nd, 2006, 09:37 AM
Look, windows is not a real time operating system. You can get 20ms using a timer CALLBACK however like the rest of Windows it wont be perfect. There are some real time products (such as Ardence)out there called real time extensions to windows that do a pretty good job of it. You can always settle for doing in fast if you dont want RTX though: :D
timerid = SetTimer(hWnd,0,20,timercb);
VOID CALLBACK timercb(HWND hWnd, UINT nMsg, UINT nIDEvent, DWORD dwTime)
{
//this code will execute every 20 MS
}
Additionally threads will work, although sleep will not be very precise sub 60 ms although it will allow it.
google for real time extensions (http://www.google.com/search?client=firefox-a&rls=org.mozilla%3Aen-US%3Aofficial_s&hl=en&q=real+time+extensions&btnG=Google+Search)
HTH,
Andreas Masur
May 22nd, 2006, 09:49 AM
Well...what kind of resolution do you need? The standard windows timer are not the best choice when you try to get resolutions below one second. They are simply not accurate enough. If you need measure within the millisecond range you need to think about other possibilities. 'WM_TIMER' messages get posted to the application's message queue, therefore you can never be sure when this message will be processed.
Besides that, 'WM_TIMER' messages are dependent on the operating system time resolution which is for example 55 milliseconds for Windows 98 and 10 milliseconds (uniprocessor x86) or 15 millisecond (multiprocessor x86) on a Windows NT (I do not have the resolutions for 2000 or XP handy, however, they should be the same).
Same applies to 'Sleep()'...calling 'Sleep()' causes an interuption of the running thread and therefore a context-switch to another thread with at least the same priority. Therefore 'Sleep()' is heavily dependent on the time-slice of the operating system which of course varies heavily...
For example, the time-slice length on a Windows NT system is dependent on the size of a quantum. The following shows the three possible quantum lengths (expressed in quantum units) for Windows NT Workstation:
- 6
- 12
- 18
The lengths can be influenced by whether a process owns the foreground window or not. The rest is basic calculation...three quantum units elapse every tick of NT's quantum-tracking timer, and a timer tick period is either 10 milliseconds (uniprocessor x86) or 15 milliseconds (multiprocessor x86). This of course is also dependent on the vendor and motherboard but that would lead too far here.
Which this calculation we would end up with the following time-slice length for a multiprocessor x86 system:
- 30 ms
- 60 ms
- 90 ms
If you need such a high resolution you need to go down on the hardware level. The following article (http://www.codeproject.com/system/timers_intro.asp) describes some other timers in detail like waitable timers that might be an option....
MikeAThon
May 22nd, 2006, 04:09 PM
As long as you understand that both Sleep and WaitForSingleObject are terribly imprecise timers (they might be worse than the 20 millisecs that you mentioned), the WaitForSingleObject approach will be better, since it will allow you to terminate the thread at any arbitrary point in time, without waiting for a current Sleep to expire. E.g.:
int timeInterval = 5000; // five seconds
int iRet = WaitForSingleObject( hAbortEvent, timeInterval );
if ( iRet==WAIT_OBJECT_0 ) return 0;
{
// .. do your stuff
}
// .. repeat
The hAbortEvent should be signalled in the main thread, and will cause the WFSO to exit immediately.
OTOH, if you use Sleep, your code would look something like this:
Sleep( 5000 );
if ( bAbortFlag==true ) return 0;
{
// .. do your stuff
}
// .. repeat
Here, your code must wait as long as 5 seconds before it can inspect the abort flag, which means that you will not be able to shut down your thread whenever you want.
Mike
tnarol
May 23rd, 2006, 03:46 AM
From what you say I understand that there are many types of timers, none of which can provide better resolution than determined by the OS.
It's OK for me to live with this issue, but I'd like to know if chosing a particular timer could change the global performance of my thread in terms of CPU time consumption or "real time" performance.
tnarol
May 23rd, 2006, 03:51 AM
the WaitForSingleObject approach will be better, since it will allow you to terminate the thread at any arbitrary point in time, without waiting for a current Sleep to expire.
Yes that's a good point.
Andreas Masur
May 24th, 2006, 02:21 PM
From what you say I understand that there are many types of timers, none of which can provide better resolution than determined by the OS.
Actually no...some of the timers don't use the resolution of the operating system but rather use the underlying hardware directly.
It's OK for me to live with this issue, but I'd like to know if chosing a particular timer could change the global performance of my thread in terms of CPU time consumption or "real time" performance.
Yes...it is pretty simple. If you want to have your thread wait for 5 ms, then using 'Sleep()' would cause it to sleep longer than by using a hardware-based timer that provides a resolution of milliseconds.
Arjay
May 24th, 2006, 03:34 PM
Resolution issues aside, there is another reason to consider WaitForSingleObject (or WaitForMultipleObjects) approach over a windows Timer. With a windows timer, part of its consistancy is dependent on what other UI messages are sent to your app (and dependent on the ability of your app to process these messages). For example, the user could seriously effect the timer by, simply moving the mouse back and forth over the application.
If you use the WFSO or WFMO method as your timer, you will take UI interactions out of the equation.
codeguru.com
Copyright Internet.com Inc., All Rights Reserved.