Windows下多媒体定时器

Windows下使用多媒体定时器,初始测试,发现很多和自己开始想的不一样。我的使用方式如下:


#include 
#include 
#pragma comment(lib,"winmm.lib")
//自己实现的一个微型日志系统
#include "Comm/MiniLogger.h"

class WinMMTimer
{
public:
    WinMMTimer():m_iTimerID(0), m_iTimeRes(10)
    {
        TIMECAPS tc;
        if(timeGetDevCaps(&tc, sizeof(TIMECAPS)) == TIMERR_NOERROR)
        {
            m_iTimeRes = min(max(tc.wPeriodMin, 1), tc.wPeriodMax);
            MINI_LOG(logDEBUG) << "Time resolution: " << m_iTimeRes;
            timeBeginPeriod(m_iTimeRes);
        }
    };

    virtual ~WinMMTimer(){
        stop();
        timeEndPeriod(m_iTimeRes);
    };

    bool start(unsigned int iInterval, DriveWorker* pWorker = 0){
        stop();
        if(iInterval < m_iTimeRes)
            iInterval = m_iTimeRes;
        m_iTimerID = timeSetEvent(iInterval, m_iTimeRes, &TimeProc,
                (DWORD)pWorker, TIME_PERIODIC);
        return (m_iTimerID != 0);
    };

    inline void stop(){
        if(m_iTimerID != 0){
            timeKillEvent(m_iTimerID);
            m_iTimerID = 0;
        }
    };

private:
    static void CALLBACK WinMMTimer::TimeProc(UINT /*uiID*/, UINT /*uiMsg*/
            , DWORD dwUser, DWORD /*dw1*/, DWORD /*dw2*/)
    {
   	    SetThreadAffinityMask(GetCurrentThread(), 0x00000001);

        MINI_LOG(logDEBUG) << "Timer on Process " << GetCurrentProcessorNumber();
        Sleep(5);
	};

private:
    unsigned long m_iTimerID;   ///< 计时器ID
    unsigned long m_iTimeRes; ///< 计时器精度
};

</pre>


* 每次定时器到来时,都会执行TimeProc函数,当前的定时时间为1ms;下一个定时到来时,是否会启动不同的线程来运行该函数。经过试验:无论在定时1ms期间, TimeProc函数是否执行完成,第二次执行该函数的线程都是相同的(线程ID相等)。

* 若前一个1ms内执行定时函数未完成,第二个1ms定时到来时,是否会重入执行定时函数。经过在TimeProc函数中使用休眠Sleep,或者循环执行某个操作,都不会造成新的线程被执行,从而不存在该函数重入的问题。原先使用Boost库的boost::mutex来进行互斥就完全没有必要了。


在追求Windows环境下高精度定时器,还参考了以下的文章:

* [Creating a High-Precision, High-Resolution, and Highly Reliable Timer, Utilising Minimal CPU Resources](http://www.codeguru.com/cpp/w-p/system/timers/article.php/c5759/Creating-a-HighPrecision-HighResolution-and-Highly-Reliable-Timer-Utilising-Minimal-CPU-Resources.htm)

* [Implement a Continuously Updating, High-Resolution Time Provider for Windows](http://msdn.microsoft.com/en-us/magazine/cc163996.aspx)
blog comments powered by Disqus