在前面的例子里使用了一个精度只能到秒级别的定时器,对于一般应用来说,已经卓卓有余,能对付大多数的情况了。但有一天,老板让你开发一个对时间精度能到毫秒级别的定时器,就显得力不从心,左思右想不得其解。假如在嵌入式系统里,往往可以直接操作定时器来实现,但在PC系统里,就不能直接操作硬件了,更何况操作系统还存在进程调度的中断,因此定时器的精度就大大打折扣。在boost库里提供了boost::asio::high_resolution_timer类,就可以实现跨平台高精度的定时功能。比如串口通讯里,每间隔500毫秒就要获取一次数据,就可以使用这样的定时器。比如正在制作录像时,就可以使用这个定时器来实现视频与语音同步。high_resolution_timer定时器理论上可以达到纳秒数量级,因此可以满足任何精度的计时了。现在来详细看下面的例子:
// boost_018.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#include <boost/asio.hpp>
#include <boost/bind.hpp>
#include <boost/thread.hpp>
#include <boost/thread/mutex.hpp>
#include <boost/asio/high_resolution_timer.hpp>
#include <iostream>
void TaskRun(int nVal)
{
//下面输出需要加锁,不能多个线程共享输出。
static boost::mutex mutexCout;
boost::lock_guard<boost::mutex> autoLock(mutexCout);
std::cout << "TaskRun: " << nVal << std::endl;
}
//封装线程组运行的类, 并且演示使用类成员函数作为线程组运行函数
//软件开发人员: 蔡军生 2013-05-12
//QQ: 9073204
class CThreadBase
{
//定义毫秒。
typedef boost::chrono::duration<long long, boost::milli> milliseconds;
public:
CThreadBase(void)
:m_Work(m_ioService),
m_HighTimer(m_ioService)
{
}
void Start(int nMaxCount)
{
//循环地创建N个线程。
for (int i = 0; i < nMaxCount; ++i)
{
m_threadGroup.create_thread(boost::bind(&CThreadBase::Run, this, i));
}
}
void Stop(void)
{
//
m_ioService.stop();
//等所有线程退出。
m_threadGroup.join_all();
}
//测试任务队列
//软件开发人员: 蔡军生 2013-05-25
//QQ: 9073204
void TestTask(void)
{
//放入几个任务。
m_ioService.post(boost::bind(TaskRun, 1));
m_ioService.post(boost::bind(TaskRun, 2));
m_ioService.post(boost::bind(TaskRun, 3));
m_ioService.post(boost::bind(TaskRun, 4));
m_ioService.post(boost::bind(TaskRun, 5));
m_ioService.post(boost::bind(TaskRun, 6));
//第一次定时器启动。
m_HighTimer.expires_from_now(milliseconds(500));
m_HighTimer.async_wait(boost::bind(&CThreadBase::Wait, this, 5));
}
private:
virtual void Run(int nVal)
{
//运行队列里的任务。
boost::system::error_code errorCode;
m_ioService.run(errorCode);
}
//
void Wait(int nSeconds)
{
//下面输出需要加锁,不能多个线程共享输出。
static boost::mutex mutexCout;
boost::lock_guard<boost::mutex> autoLock(mutexCout);
std::cout << "Wait: " << nSeconds << "ms" << std::endl;
//下一次定时器。
m_HighTimer.expires_from_now(milliseconds(5000));
m_HighTimer.async_wait(boost::bind(&CThreadBase::Wait, this, 5));
}
private:
//定义一个任务队列。
boost::asio::io_service m_ioService;
boost::asio::io_service::work m_Work;
//定义一个线程组对象。
boost::thread_group m_threadGroup;
//创建高精度定时器
boost::asio::high_resolution_timer m_HighTimer;
};
int _tmain(int argc, _TCHAR* argv[])
{
//
CThreadBase threadBase;
//设置最大的线程个数。
threadBase.Start(3);
threadBase.TestTask();
Sleep(20000);
threadBase.Stop();
system("pause");
return 0;
}
从上面的例子,可以看到先包含头文件:
boost/asio/high_resolution_timer.hpp
接着定义毫秒的周期计时类型:
typedef boost::chrono::duration<long long, boost::milli>milliseconds;
然后就可以使用expires_from_now来计算定时器的时间了。这样就可以使用定时器周期性地工作,使用起来跟普通的定时器一样,没有太大的区别。