由于您使用 C++ 进行设计,因此您可以使用 Boost ASIO 计时器。我还设计了一个基于它们的 Timer 类,它工作得很好,没有任何线程 - 它使用对操作系统的异步调用,所以基本上你只需要定义一个回调,它将在定时器到期时调用,然后调用定时器的 async_wait 函数,它是非阻塞的。当您声明您的计时器对象时,您只需向它传递一个 io_service 对象,该对象是操作系统的 ASIO 接口。该对象负责为您的异步请求和回调提供服务,因此您可以调用它的阻塞方法run。在我的情况下,我不能让主线程阻塞,所以我只有一个线程阻塞了这个独特的调用。
您可以在此处找到有关如何使用 Boost ASIO 异步计时器的示例:
http://www.boost.org/doc/libs/1_52_0/doc/html/boost_asio/tutorial/tuttimer2.html
我的 AbstractAsioTimer 类被设计为子类化,因此 onTimerTick 方法将特定于派生类结束。尽管您的需求可能会有所不同,但这可能是一个很好的起点:
abstractasiotimer.hpp:
#ifndef _ABSTRACTASIOTIMER_HPP_
#define _ABSTRACTASIOTIMER_HPP_
#include <boost/asio.hpp>
/**
* Encapsulates a POSIX timer with microsecond resolution
*/
class AbstractAsioTimer
{
public:
/**
* Instantiates timer with the desired period
* @param io ASIO interface object to the SO
* @param timeout time in microseconds for the timer handler to be executed
*/
AbstractAsioTimer(boost::asio::io_service& io, unsigned int timeout);
/**
* Destructor
*/
virtual ~AbstractAsioTimer();
/**
* Starts timer operation
*/
void timerStart();
/**
* Stops timer operation
*/
void timerStop();
/**
* Returns timer operation state
*/
bool isRunning() const;
/**
* Returns a reference to the underlying io_service
*/
boost::asio::io_service& get_io_service();
protected:
/**
* Timer handler to execute user specific code
* @note must be reimplemented in derived classes
*/
virtual void onTimerTick() = 0;
private:
/**
* Callback to be executed on timer expiration. It is responsible
* for calling the 'onTimerTick' method and restart the timer if
* it remains active
*/
void timerExpired(const boost::system::error_code& error);
boost::asio::deadline_timer timer; /**< ASIO timer object */
unsigned int timeout; /**< Timer period in microseconds */
bool running; /**< Flag to indicate whether the timer is active */
};
#endif
abstractasiotimer.cpp:
#include <iostream>
#include <boost/bind.hpp>
#include <boost/concept_check.hpp>
#include "abstractasiotimer.hpp"
using namespace boost::asio;
AbstractAsioTimer::AbstractAsioTimer(boost::asio::io_service& io,
unsigned int timeout):
timer(io), timeout(timeout),
running(false)
{
}
AbstractAsioTimer::~AbstractAsioTimer()
{
running = false;
timer.cancel();
}
void AbstractAsioTimer::timerExpired(const boost::system::error_code& error) {
if (!error) {
onTimerTick();
//Restart timer
timerStart();
}
else {
running = false;
std::cerr << "Timer stopped: " << error.message() << std::endl;
}
}
void AbstractAsioTimer::timerStart()
{
timer.expires_from_now(boost::posix_time::microseconds(timeout));
timer.async_wait(boost::bind(&AbstractAsioTimer::timerExpired,
this, placeholders::error));
running = true;
}
void AbstractAsioTimer::timerStop() {
running = false;
timer.cancel();
}
bool AbstractAsioTimer::isRunning() const {
return running;
}
io_service& AbstractAsioTimer::get_io_service()
{
return timer.get_io_service();
}