C++ 毫秒定时器

本文介绍了一个低分辨率定时器类LRTimer,它拥有独立的计时线程,并允许设置外部回调函数,在预定义的时间间隔内调用。最小的定时器间隔为1毫秒。文章提供了详细的使用示例。
  1. /*******************************************************************************
  2. * LRTimer.h                                                                    *
  3. *                                                                              *
  4. * Written by Max Gurdziel 2005 under GNU General Public License                *
  5. * contact me: max[at]remoteSOS[dot]com                                         *
  6. *                                                                              *
  7. * LRTimer is a low resolution timer class with own timing thread. It allows    *
  8. *  an external callback function to be supplied that will be called in         *
  9. *  pre-defined time intervals.                                                 *
  10. *  The smallest timer interval you can use is 1ms.                             *
  11. *                                                                              *
  12. * Tested with gcc mingw & Visual C++ 6.0 under WindowsXP Home and Pro          *
  13. *                                                                              *
  14. *                                                                              *
  15. *     LRTimer timer;                                  // define LRTimer object *
  16. *     timer.setInterval(100);                         // set interval of 100ms *
  17. *     timer.setCallbackProc(&myCallbackFunction, 0);  // set callback function *
  18. *                                                     // it's prototype is:    *
  19. *                               //     void myCallbackFunction(void* pParam);  *
  20. *                                                                              *
  21. *     timer.start();            // start the timer                             *
  22. *     ....                                                                     *
  23. *     timer.stop();             // stops the timer                             *
  24. *     ....                                                                     *
  25. *     timer.start(200);         // starts timer with new interval              *
  26. *                                                                              *
  27. *                                                                              *
  28. *   Example code:                                                              *
  29. *   Copy and paste below sample code to test LRTimer                           *
  30. *                                                                              *
  31. ________________________________________________________________________________
  32. #include <stdlib.h>
  33. #include "LRTimer.h"
  34. // define callback function
  35. //
  36. static void myCallback(void* data) 
  37. {
  38.     static DWORD cnt = 0;
  39.     char c;
  40.     cnt++;
  41.     switch (cnt % 4) 
  42.     {
  43.     case 0: c = '|'; break;
  44.     case 1: c = '/'; break;
  45.     case 2: c = '-'; break;
  46.     case 3: c = '//';
  47.     }
  48.     printf("/b%c",c);
  49. }
  50. int main(int argc, char *argv[]) 
  51. {
  52.     LRTimer lrt;
  53.     lrt.setCallbackProc(&myCallback, NULL); // set the callback function by reference
  54.     lrt.setInterval(50);                    // set delay interval in miliseconds
  55.     lrt.start();                            // start the timer
  56.     getchar();                              // let it run for a while - press Enter
  57.     lrt.stop();                             // stop the timer
  58.     getchar();                              // wait to show it's stopped - Enter
  59.     lrt.start(200);                         // start with different delay
  60.     getchar();
  61.     lrt.stop();
  62.     system("PAUSE");
  63.     return 0;
  64. }
  65. ________________________________________________________________________________
  66. *                                                                              *
  67. * Permission to use, copy, modify, and distribute this software and its        *
  68. * documentation under the terms of the GNU General Public License is hereby    *
  69. * granted. No representations are made about the suitability of this software  *
  70. * for any purpose. It is provided "as is" without express or implied warranty. *
  71. * See http://www.gnu.org/copyleft/gpl.html for more details.                   *
  72. *                                                                              *
  73. * All I ask is that if you use LRTimer in your project retain the              *
  74. * copyright notice. If you have any comments and suggestions please email me   *
  75. * max[at]remoteSOS[dot]com                                                     *
  76. *                                                                              *
  77. *******************************************************************************/
  78. #ifndef LRTIMER_H__
  79. #define LRTIMER_H__
  80. #ifndef _WIN32_WINNT
  81. #define _WIN32_WINNT 0x0500
  82. #endif
  83. // compile with: /MT /D "_X86_" /c
  84. // processor: x86
  85. #include <windows.h>
  86. #include <process.h>    /* _beginthread, _endthread */
  87. #include <stdio.h>
  88. #include <assert.h>
  89. // define a second in terms of 100ns - used with waitable timer API
  90. #define _SECOND 10000
  91. typedef VOID (*LRTCallbackEventProc)(VOID*);
  92. class LRTimer 
  93. {
  94. public:
  95.     // default constructor with 1 second interval
  96.     LRTimer(DWORD dwInterval=1000);
  97.     // default destructor
  98.     ~LRTimer();
  99.     
  100.     // starts timer by creating new thread. interval must be set earlier
  101.     VOID start();
  102.     
  103.     // starts timer with given interval in miliseconds
  104.     VOID start(DWORD _interval_ms);
  105.     
  106.     // stops the timer
  107.     VOID stop();
  108.     
  109.     // sets time interval in miliseconds
  110.     VOID setInterval(DWORD _interval_ms);
  111.     
  112.     // returns time interval in ms
  113.     DWORD getInterval();
  114.     
  115.     // sets function that will be called on time expiration
  116.     VOID setCallbackProc( LRTCallbackEventProc pcbEventProc,  VOID* pcbParam );
  117.     // returns true if LRtimer is currently running
  118.     BOOL isRunning();
  119.     // It should be used if the worker class will use CRT functions
  120.     static HANDLE CrtCreateThread(LPSECURITY_ATTRIBUTES lpsa, DWORD dwStackSize, LPTHREAD_START_ROUTINE pfnThreadProc, void *pvParam, DWORD dwCreationFlags, DWORD *pdwThreadId) throw()
  121.     {
  122.         // sanity check for pdwThreadId
  123.         assert(sizeof(DWORD) == sizeof(unsigned int)); 
  124.         // _beginthreadex calls CreateThread which will set the last error value before it returns
  125.         return (HANDLE) _beginthreadex(lpsa, dwStackSize, (unsigned int (__stdcall *)(void *)) pfnThreadProc, pvParam, dwCreationFlags, (unsigned int *) pdwThreadId);
  126.     }
  127. private:
  128.     DWORD   m_dwInterval;               // interval between alarms
  129.     LRTCallbackEventProc m_pCallback;   // pointer to user callback function
  130.     VOID                *m_pcbParam;    // pointer to user callback parameter
  131.     BOOL    m_bRunning;                 // timer running state
  132.     HANDLE  m_hTimerThread;             // handle to timer thread
  133.     DWORD   m_iID;                      // timer thread id - added for compatibility with Win95/98
  134.     // timer clocking tread runtine
  135.     virtual DWORD WINAPI timerThread();
  136.     // wrapper to thread runtine so it can be used within a class
  137.     static  DWORD  WINAPI timerThreadAdapter(PVOID _this) 
  138.     {
  139.         return ((LRTimer*) _this)->timerThread();
  140.     }
  141.     // timer callback APC procedure called when timer is signaled
  142.     virtual VOID CALLBACK TimerAPCProc(LPVOIDDWORDDWORD);
  143.     // wrapper to callback APC procedure so it can be used within a class
  144.     static  VOID CALLBACK TimerAPCProcAdapter(PVOID _this, DWORD a1=0, DWORD a2=0) 
  145.     {
  146.         ((LRTimer*) _this)->TimerAPCProc( NULL, a1, a2 );
  147.     }
  148. };
  149. #endif

 

  1. /*******************************************************************************
  2. * LRTimer.cpp                                                                  *
  3. *                                                                              *
  4. * Written by Max Gurdziel 2005 under GNU General Public License                *
  5. * contact me: max[at]remoteSOS[dot]com                                         *
  6. *                                                                              *
  7. * LRTimer is a low resolution timer class with own timing thread. It allows    *
  8. *  an external callback function to be supplied that will be called in         *
  9. *  pre-defined time intervals. The smallest timer interval you can use is 1ms. *
  10. *                                                                              *
  11. *  See header file for more info, usage information and example                *
  12. *                                                                              *
  13. *                                                                              *
  14. *                                                                              *
  15. * Permission to use, copy, modify, and distribute this software and its        *
  16. * documentation under the terms of the GNU General Public License is hereby    *
  17. * granted. No representations are made about the suitability of this software  *
  18. * for any purpose. It is provided "as is" without express or implied warranty. *
  19. * See http://www.gnu.org/copyleft/gpl.html for more details.                   *
  20. *                                                                              *
  21. * All I ask is that if you use LRTimer in your project you retain the          *
  22. * copyright notice. If you have any comments and suggestions please email me   *
  23. * max[at]remoteSOS[dot]com                                                     *
  24. *                                                                              *
  25. * 2008-6-23 Modified by ZhangLiang                                             *
  26. *                                                                              *
  27. *******************************************************************************/
  28. #include "stdafx.h"
  29. #include "LRTimer.h"
  30. #ifndef _WIN32_WINNT
  31. #define _WIN32_WINNT 0x0500
  32. #endif
  33. LRTimer::LRTimer(DWORD dwInterval):
  34.     m_dwInterval(dwInterval),
  35.     m_bRunning(FALSE),
  36.     m_pCallback(NULL),
  37.     m_pcbParam(NULL),
  38.     m_hTimerThread(0)
  39. {}
  40. LRTimer::~LRTimer()
  41. {}
  42. VOID CALLBACK LRTimer::TimerAPCProc(LPVOIDDWORDDWORD
  43. {
  44.     // call custom callback function
  45.     if (NULL != m_pCallback)
  46.         (*m_pCallback)(m_pcbParam);
  47. #ifdef _DEBUG
  48.     else
  49.         printf("No callback function set/n");
  50. #endif
  51. }
  52. DWORD WINAPI LRTimer::timerThread() 
  53. {
  54.     HANDLE          hTimer;
  55.     BOOL            bSuccess;
  56.     LARGE_INTEGER   liDueTime;
  57.     CHAR            szError[255];
  58.     CHAR            szTimerName[16];
  59.     sprintf_s(szTimerName, "LRT_%x", (DWORD)(DWORD_PTR)this);
  60.     
  61.     if ( hTimer = CreateWaitableTimerA( NULL, FALSE, szTimerName ) )
  62.         liDueTime.QuadPart=-(LONGLONG)m_dwInterval * _SECOND;
  63.     bSuccess = SetWaitableTimer(
  64.                   hTimer,                            // Handle to the timer object
  65.                   &liDueTime,                        // When timer will become signaled first time
  66.                   m_dwInterval,                      // Periodic timer interval
  67.                   TimerAPCProcAdapter,               // Completion routine
  68.                   this,                              // Argument to the completion routine
  69.                   FALSE );                           // Do not restore a suspended system
  70.     
  71.     if ( bSuccess ) {
  72.         while (m_bRunning)
  73.             SleepEx(1, TRUE);   // SleepEx(0, TRUE) consumes 100% CPU usage
  74.         CancelWaitableTimer(hTimer);
  75.     } else {
  76.         wsprintfA( szError, "SetWaitableTimer failed with Error %d.", GetLastError() );
  77. #ifdef _DEBUG
  78.         MessageBoxA( NULL, szError, "Error", MB_ICONEXCLAMATION );
  79. #endif
  80.         return 1;
  81.     }
  82.     CloseHandle(hTimer);
  83.     return 0;
  84. }
  85. VOID LRTimer::start() 
  86. {
  87.     m_bRunning = TRUE;
  88.     if (m_hTimerThread != 0) 
  89.         stop();
  90. #ifndef _INC_CRTDEFS
  91.     m_hTimerThread = CreateThread(NULL, 0, timerThreadAdapter, this, 0, &m_iID);
  92. #else
  93.     m_hTimerThread = CrtCreateThread(NULL, 0, timerThreadAdapter, this, 0, &m_iID);
  94. #endif
  95.     if (m_hTimerThread == NULL) 
  96.     {
  97. #ifdef _DEBUG
  98.         printf( "CreateThread failed (%d)/n", GetLastError() );
  99. #endif
  100.         return;
  101.     }
  102. }
  103. VOID LRTimer::start(DWORD _interval_ms) 
  104. {
  105.     setInterval(_interval_ms);
  106.     start();
  107. }
  108. VOID LRTimer::stop()
  109. {
  110.     m_bRunning = FALSE;
  111.     CloseHandle(m_hTimerThread);
  112.     m_hTimerThread = 0;
  113. }
  114. VOID LRTimer::setInterval(DWORD _interval_ms)
  115. {
  116.     m_dwInterval = _interval_ms;
  117. }
  118. DWORD LRTimer::getInterval()
  119. {
  120.     return m_dwInterval;
  121. }
  122. VOID LRTimer::setCallbackProc( LRTCallbackEventProc pcbEventProc, VOID* pcbParam) 
  123. {
  124.     m_pCallback = pcbEventProc;
  125.     m_pcbParam = pcbParam;
  126. }
  127. BOOL LRTimer::isRunning() 
  128. {
  129.     return m_bRunning;
  130. }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

车斗

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值