程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> 關於C++ >> C++毫秒定時器

C++毫秒定時器

編輯:關於C++

/******************************************************************** ***********
* LRTimer.h                                                                     *
*                                                                               *
* Written by Max Gurdziel 2005 under GNU General Public License                 *
* contact me: max[at]remoteSOS[dot]com                                          *
*                                                                               *
* LRTimer is a low resolution timer class with own timing thread. It allows     *
*  an external callback function to be supplied that will be called in          *
*  pre-defined time intervals.                                                  *
*  The smallest timer interval you can use is 1ms.                              *
*                                                                               *
* Tested with gcc mingw & Visual C++ 6.0 under WindowsXP Home and Pro           *
*                                                                               *
*                                                                               *
*     LRTimer timer;                                   // define LRTimer object *
*     timer.setInterval(100);                          // set interval of 100ms *
*     timer.setCallbackProc(&myCallbackFunction, 0);  // set callback function *
*                                                      // it's prototype is:    *
*                               //     void myCallbackFunction(void* pParam);  *
*                                                                               *
*     timer.start();            // start the timer                              *
*     ....                                                                      *
*     timer.stop();             // stops the timer                              *
*     ....                                                                      *
*     timer.start(200);         // starts timer with new interval               *
*                                                                               *
*                                                                               *
*   Example code:                                                               *
*   Copy and paste below sample code to test LRTimer                            *
*                                                                               *
______________________________________________________________________________ __

#include <stdlib.h>
#include "LRTimer.h"


// define callback function
//
static void myCallback(void* data)
{
    static DWORD cnt = 0;
    char c;
    cnt++;
    switch (cnt % 4)
    {
    case 0: c = '|'; break;
    case 1: c = '/'; break;
    case 2: c = '-'; break;
    case 3: c = '\\';
    }
    printf("\b%c",c);
}


int main(int argc, char *argv[])
{
    LRTimer lrt;
    lrt.setCallbackProc(&myCallback, NULL); // set the callback function by reference
    lrt.setInterval(50);                    // set delay interval in miliseconds
    lrt.start();                            // start the timer
    getchar();                              // let it run for a while - press Enter
    lrt.stop();                             // stop the timer
    getchar();                              // wait to show it's stopped - Enter
    lrt.start(200);                         // start with different delay
    getchar();
    lrt.stop();
    system("PAUSE");
    return 0;
}

______________________________________________________________________________ __
*                                                                               *
* Permission to use, copy, modify, and distribute this software and its         *
* documentation under the terms of the GNU General Public License is hereby     *
* granted. No representations are made about the suitability of this software   *
* for any purpose. It is provided "as is" without express or implied warranty. *
* See http://www.gnu.org/copyleft/gpl.html for more details.                    *
*                                                                               *
* All I ask is that if you use LRTimer in your project retain the               *
* copyright notice. If you have any comments and suggestions please email me    *
* max[at]remoteSOS[dot]com                                                      *
*                                                                               *
****************************************************************************** */

#ifndef LRTIMER_H__
#define LRTIMER_H__

#ifndef _WIN32_WINNT
#define _WIN32_WINNT 0x0500
#endif

// compile with: /MT /D "_X86_" /c
// processor: x86

#include <windows.h>
#include <process.h> /* _beginthread, _endthread */
#include <stdio.h>
#include <assert.h>

// define a second in terms of 100ns - used with waitable timer API
#define _SECOND 10000

typedef VOID (*LRTCallbackEventProc)(VOID*);

class LRTimer 
{
public:
    // default constructor with 1 second interval
    LRTimer(DWORD dwInterval=1000);

    // default destructor
    ~LRTimer();

    // starts timer by creating new thread. interval must be set earlier
    VOID start();

    // starts timer with given interval in miliseconds
    VOID start(DWORD _interval_ms);

    // stops the timer
    VOID stop();

    // sets time interval in miliseconds
    VOID setInterval(DWORD _interval_ms);

    // returns time interval in ms
    DWORD getInterval();

    // sets function that will be called on time expiration
    VOID setCallbackProc( LRTCallbackEventProc pcbEventProc,  VOID* pcbParam );

    // returns true if LRtimer is currently running
    BOOL isRunning();

    // It should be used if the worker class will use CRT functions
    static HANDLE CrtCreateThread(LPSECURITY_ATTRIBUTES lpsa, DWORD dwStackSize, LPTHREAD_START_ROUTINE pfnThreadProc, void *pvParam, DWORD dwCreationFlags, DWORD *pdwThreadId) throw()
    {
        // sanity check for pdwThreadId
        assert(sizeof(DWORD) == sizeof(unsigned int)); 

        // _beginthreadex calls CreateThread which will set the last error value before it returns
        return (HANDLE) _beginthreadex(lpsa, dwStackSize, (unsigned int (__stdcall *)(void *)) pfnThreadProc, pvParam, dwCreationFlags, (unsigned int *) pdwThreadId);
    }

private:
    DWORD   m_dwInterval;  // interval between alarms

    LRTCallbackEventProc m_pCallback;  // pointer to user callback function
    VOID                *m_pcbParam; // pointer to user callback parameter

    BOOL    m_bRunning;  // timer running state
    HANDLE  m_hTimerThread;  // handle to timer thread
    DWORD   m_iID;  // timer thread id - added for compatibility with Win95/98

    // timer clocking tread runtine
    virtual DWORD WINAPI timerThread();

    // wrapper to thread runtine so it can be used within a class
    static  DWORD  WINAPI timerThreadAdapter(PVOID _this)
    {
        return ((LRTimer*) _this)->timerThread();
    }

    // timer callback APC procedure called when timer is signaled
    virtual VOID CALLBACK TimerAPCProc(LPVOID, DWORD, DWORD);

    // wrapper to callback APC procedure so it can be used within a class
    static  VOID CALLBACK TimerAPCProcAdapter(PVOID _this, DWORD a1=0, DWORD a2=0)
    {
        ((LRTimer*) _this)->TimerAPCProc( NULL, a1, a2 );
    }
};

#endif


/***************************************************************************** **
* LRTimer.cpp                                                                   *
*                                                                               *
* Written by Max Gurdziel 2005 under GNU General Public License                 *
* contact me: max[at]remoteSOS[dot]com                                          *
*                                                                               *
* LRTimer is a low resolution timer class with own timing thread. It allows     *
*  an external callback function to be supplied that will be called in          *
*  pre-defined time intervals. The smallest timer interval you can use is 1ms. *
*                                                                               *
*  See header file for more info, usage information and example                 *
*                                                                               *
*                                                                               *
*                                                                               *
* Permission to use, copy, modify, and distribute this software and its         *
* documentation under the terms of the GNU General Public License is hereby     *
* granted. No representations are made about the suitability of this software   *
* for any purpose. It is provided "as is" without express or implied warranty. *
* See http://www.gnu.org/copyleft/gpl.html for more details.                    *
*                                                                               *
* All I ask is that if you use LRTimer in your project you retain the           *
* copyright notice. If you have any comments and suggestions please email me    *
* max[at]remoteSOS[dot]com                                                      *
*                                                                               *
* 2008-6-23 Modified by ZhangLiang                                              *
*                                                                               *
****************************************************************************** */
#include "stdafx.h"

#include "LRTimer.h"

#ifndef _WIN32_WINNT
#define _WIN32_WINNT 0x0500
#endif

LRTimer::LRTimer(DWORD dwInterval):
    m_dwInterval(dwInterval),
    m_bRunning(FALSE),
    m_pCallback(NULL),
    m_pcbParam(NULL),
    m_hTimerThread(0)
{}

LRTimer::~LRTimer()
{}

VOID CALLBACK LRTimer::TimerAPCProc(LPVOID, DWORD, DWORD)
{
    // call custom callback function
    if (NULL != m_pCallback)
        (*m_pCallback)(m_pcbParam);

#ifdef _DEBUG
    else
        printf("No callback function set\n");
#endif
}

DWORD WINAPI LRTimer::timerThread()
{
    HANDLE          hTimer;
    BOOL            bSuccess;
    LARGE_INTEGER   liDueTime;
    CHAR            szError[255];

    CHAR            szTimerName[16];
    sprintf_s(szTimerName, "LRT_%x", (DWORD)(DWORD_PTR)this);

    if ( hTimer = CreateWaitableTimerA( NULL, FALSE, szTimerName ) )
        liDueTime.QuadPart=-(LONGLONG)m_dwInterval * _SECOND;

    bSuccess = SetWaitableTimer(
                  hTimer,                             // Handle to the timer object
                  &liDueTime,                         // When timer will become signaled first time
                  m_dwInterval,                       // Periodic timer interval
                  TimerAPCProcAdapter,                // Completion routine
                  this,                               // Argument to the completion routine
                  FALSE );                            // Do not restore a suspended system

    if ( bSuccess ) {
        while (m_bRunning)
            SleepEx(1, TRUE);   // SleepEx(0, TRUE) consumes 100% CPU usage
        CancelWaitableTimer(hTimer);
    } else {
        wsprintfA( szError, "SetWaitableTimer failed with Error % d.", GetLastError() );
#ifdef _DEBUG
        MessageBoxA( NULL, szError, "Error", MB_ICONEXCLAMATION );
#endif
        return 1;
    }
    CloseHandle(hTimer);
    return 0;
}


VOID LRTimer::start()
{
    m_bRunning = TRUE;

    if (m_hTimerThread != 0)
        stop();

#ifndef _INC_CRTDEFS
    m_hTimerThread = CreateThread(NULL, 0, timerThreadAdapter, this, 0, &m_iID);
#else
    m_hTimerThread = CrtCreateThread(NULL, 0, timerThreadAdapter, this, 0, &m_iID);
#endif

    if (m_hTimerThread == NULL)
    {
#ifdef _DEBUG
        printf( "CreateThread failed (%d)\n", GetLastError() );
#endif
        return;
    }
}

VOID LRTimer::start(DWORD _interval_ms)
{
    setInterval(_interval_ms);
    start();
}

VOID LRTimer::stop()
{
    m_bRunning = FALSE;
    CloseHandle(m_hTimerThread);
    m_hTimerThread = 0;
}

VOID LRTimer::setInterval(DWORD _interval_ms)
{
    m_dwInterval = _interval_ms;
}

DWORD LRTimer::getInterval()
{
    return m_dwInterval;
}

VOID LRTimer::setCallbackProc( LRTCallbackEventProc pcbEventProc, VOID* pcbParam)
{
    m_pCallback = pcbEventProc;
    m_pcbParam = pcbParam;
}

BOOL LRTimer::isRunning()
{
    return m_bRunning;
}

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved