软件注册站
热情软件屋

 
如何在Windows实现准确的定时
编号: QA001813    
建立日期: 1999年10月5日 最后修改日期: 1999年10月6日
所属类别: C/C++ - 其他方面
   
    VC++,Delphi
    简体中文版 Windows 98
    1、Windows中最低级的定时结构是如何实现的?
    2、如何在Windows避免其他消息对定时的影响,从而实现实时、准确的定时?(蚯蚓)
   
    The system has WM_TIMER which gives about 50ms resolution, and Multimedia Timers which can do about 1ms.
    1)For using the Multimidia:
    To determine the minimum and maximum timer resolutions supported by the timer services, use the timeGetDevCaps function. This function fills the wPeriodMin and wPeriodMax members of the TIMECAPS structure with the minimum and maximum resolutions. This range can vary across computers and Windows platforms.
    After you determine the minimum and maximum available timer resolutions, you must establish the minimum resolution you want your application to use. Use the timeBeginPeriod and timeEndPeriod functions to set and clear this resolution. You must match each call to timeBeginPeriod with a call to timeEndPeriod, specifying the same minimum resolution in both calls. An application can make multiple timeBeginPeriod calls, as long as each call is matched with a call to timeEndPeriod.
    In both timeBeginPeriod and timeEndPeriod, the uPeriod parameter indicates the minimum timer resolution, in milliseconds. You can specify any timer resolution value within the range supported by the timer.(主持人注,参考QA001022 "VC++中使用高精度定时器"
    
    2)There are a few instructions included in the Pentium instruction set,for precise timing and delays. Those are instructions to read the present state of a high-speed counter and also to get the frequency of the counter. These instructions are wrapped in C++ by the two functions called: QueryPerformanceCounter and QueryPerformanceFrequency.
    
    3)Using the GetTickCount()
    It is possible to adjust a simple for() loop that contains _asm {NOP} and get a reasonable delay accuracy.
    
    Note: The timer releated functions are always processor independent. So in your code, you'd better dynamically calculate your delay count based on the runtime test.
    
    Maybe it is better to put this doc on your web site and make a link to the question regarding to the High Resolution Timer question. And it is not me who wrote this doc.
    下文的原始连接为:http://www.sysinternals.com/ntw2k/info/timer.shtml
    ==========================
    Inside Windows NT High Resolution Timers
    Copyright 1997 Mark Russinovich Last Updated July 9, 1997
    Note: The information presented here is the result of my own study. No source code was used.
    Introduction High resolution timers are desirable in a wide variety of different applications. For example, the most common use of such timers in Windows is by multimedia applications that are producing sound or audio that require precise control. MIDI is a perfect example because MIDI sequencers must maintain the pace of MIDI events with 1 millisecond accuracy. This article describes how high resolution timers are implemented in NT and documents NtSetTimerResolution and NtQueryTimerResolution, the NT kernel functions that manipulate and return information about the system clock. Unfortunately, NtSetTimerResolution and NtQueryTimerResolution are not exported by the NT kernel, so they are not available to kernel-mode device drivers. The Timer API Windows NT bases all of its timer support off of one system clock interrupt, which by default runs at a 10 millisecond granularity. This is therefore the resolution of standard Windows timers.
    When a multimedia application uses the timeBeginPeriod mutlimedia API, which is exported by the Windows NT dynamic link library WINMM.DLL, the call is redirected into the Windows NT kernel-mode function NtSetTimerResolution, which is exported by the native Windows NT library NTDLL.DLL.
    NtSetTimerResolution and NtQueryTimerResolution are defined as follows. All times are specifified in hundreds of nanoseconds. NTSTATUS NtSetTimerResolution
    
    IN ULONG RequestedResolution,
    IN BOOLEAN Set,
    OUT PULONG ActualResolution
    );
    Parameters
    RequestedResolution
    The desired timer resolution. Must be within the legal range of system timer values supported by NT. On standard x86 systems this is 1-10 milliseconds. Values that are within the acceptable range are rounded to the next highest millisecond boundary by the standard x86 HAL. This parameter is ignored if the Set parameter is FALSE.
    Set This is TRUE if a new timer resolution is being requested, and FALSE if the
    application is indicating it no longer needs a previously implemented resolution.
    ActualResolution The timer resolution in effect after the call is returned in this parameter.
    Comments
    NtSetTimerResolution returns STATUS_SUCCESS if the resolution requested is within the valid range of timer values. If Set is FALSE, the caller must have made a previous call to NtSetTimerResolution or STATUS_TIMER_RESOLUTION_NOT_SET is returned.
    
    NTSTATUS NtQueryTimerResolution
    OUT PULONG MinimumResolution,
    OUT PULONG Maximum Resolution,
    OUT PULONG ActualResolution
    );
    Parameters
    MinimumResolution
    The minimum timer resolution. On standard x86 systems this is 0x2625A, which is about 10 milliseconds
    MaximumResolution
    The maximum timer resolution. On standard x86 systems this is 0x2710, which
    is about 1 millisecond.
    ActualResolution
    This is the current resolution of the system clock.
    Implementation Details NtSetTimerResolution can be called to set timer resolutions by more than on application. To support a subsequent process setting a timer resolution without violating the resolution assumptions of a previous caller, NtSetTimerResolution never lowers the timer's resolution, only raises it. For example, if a process sets the resolution to 5 milliseconds, subequent calls to set the resolution to between 5 and 10 millseconds will return a status code indicating success, but the timer will be left at 5 milliseconds.
    NtSetTimerResolution also keeps track of whether a process has set the timer resolution in its process control block, so that when a call is made with Set equal to FALSE it can verify that the caller has previously requested a new resolution. Every time a new resolution is set a global counter is incremented, and every time it is reset the counter is decremented. When the counter becomes 0 on a reset call the timer is changed back to its default rate, otherwise no action is taken. Again, this preserves the timer resolution assumptions of all the applications that have requested high
    resolution timers by guaranteeing that the resolution will be at least as good as what they specified.
    ==========================
    
    相关问题:
    QA004842 "timeGetTime函数延时不准"

    

此问题由Xingong Wu回答。

附加关键字:编程, 源程序, programming, source code, C/C++, MFC, C++ Builder, Borland C++, Turbo C, C, BCB, 其他方面,

   
 
把这个问题推荐给朋友
   
 
   
您的意见类别
您的名字
您的电子邮件
您的建议(请尽可能详细)
 
 

版权所有 1997-2008 热情软件屋
如果您有任何建议和意见, 请给我发个电子邮件 askpro@china-askpro.com
Web Designed by ZebraStudio