boost库在工作(24)任务之四

在软件开发里,经常会遇到这样的情况,比如客户让我们开发的软件要求每隔半小时,就要备份一次数据,以便避免数据丢失。又比如在开发一个游戏网络服务器时,需要不断检查客户端连接上来的数据连接是否还有效,这时也需要使用一个任务来检查客户端的连接是否还有心跳包过来,如果没有心跳包,就可以把这个连接断开,释放相关的资源,避免服务器的资源永远占用,导致服务器运行时间长了就会死机。面对这些情况,在有界面的情况下,往往通过界面上的定时器来提供定时服务来解决这些问题。在没有界面的情况之下,往往使用一个线程来解决,虽然都可以解决,但相比boost库里的boost::asio::deadline_timer对象来解决,显示有点复杂,代码有点多,维护性也不好。下面就来看例子,怎么样简单优美地解决心跳包检查的问题:
// boost_017.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/deadline_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;
}

//封装线程组运行的类, 并且演示使用类成员函数作为线程组运行函数

class CThreadBase
{
public:
	CThreadBase(void)
		:m_Work(m_ioService),
		m_HeartBeat(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();
	}
	//测试任务队列

	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_HeartBeat.expires_from_now(boost::posix_time::milliseconds(5));
		m_HeartBeat.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 << std::endl;

		//下一次定时器。
		m_HeartBeat.expires_from_now(boost::posix_time::seconds(5));
		m_HeartBeat.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::deadline_timer m_HeartBeat;
};


int _tmain(int argc, _TCHAR* argv[])
{
	//
	CThreadBase threadBase;

	//设置最大的线程个数。
	threadBase.Start(3);
	threadBase.TestTask();

	Sleep(20000);
	threadBase.Stop();

	system("pause");

	return 0;
}

在这个例子里,定义了定时器boost::asio::deadline_timer对象HeartBeat,然后调用函数expires_from_now来设置定时的时间,最后调用函数async_wait异步调用函数Wait来执行。为了达到每间隔5秒调用一次,在函数Wait里递归地调用函数expires_from_now和函数async_wait。因此在这个例子里,函数Wait就是定时执行的函数,在这个函数添加代码,就可以实现定时地检查心跳包,定时备份的工作。这个例子输出的结果如下:

TaskRun: 1

TaskRun: 2

TaskRun: 3

TaskRun: 4

TaskRun: 5

Wait: 5

TaskRun: 6

Wait: 5

Wait: 5

Wait: 5

请按任意键继续. . .


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值