现在的位置: 首页 > 综合 > 正文

boost库在工作(23)任务之三

2013年05月17日 ⁄ 综合 ⁄ 共 2453字 ⁄ 字号 评论关闭

在前面的多任务执行里,因为有多个线程执行,只要放到任务队列里的任务都会执行,但这些任务执行顺序是随机的,没有固定的顺序,也就是说放入队列早的任务不一定就是早执行,放入队列迟的任务也不一定后执行。这样没有顺序的执行性是多线程的本来特性,虽然可以使用锁对象来同步一个对象不被多个线程同时访问,但它是没有办法确保任务之间的有序访问同一个资源。这时,就需要引入一个对象io_service::strand,有它来保证放入任务队列的任务,可以按它放入任务队列的顺序来执行。比如使用一个线程池来执行写多个文件,每一个文件都是有序的数据,而多个文件之间是无序的,这样在每一个文件都使用io_service::strand放入,而多个io_service::strand对象之间是无序的,这样确保每一个文件写是有序队列,而多个文件可以无序执行,达到最大性能地使用CPU资源。如下面的例子:

// boost_016.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 <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
{
public:
	CThreadBase(void)
		:m_Work(m_ioService),
		m_Strand(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-04-28
	//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));	
	}

	//测试有序任务队列
	//软件开发人员: 蔡军生  2013-05-12
	//QQ: 9073204
	void TestStrandTask(void)
	{
		//放入几个任务。
		m_Strand.post(boost::bind(TaskRun, 1));
		m_Strand.post(boost::bind(TaskRun, 2));
		m_Strand.post(boost::bind(TaskRun, 3));	
		m_Strand.post(boost::bind(TaskRun, 4));
		m_Strand.post(boost::bind(TaskRun, 5));
		m_Strand.post(boost::bind(TaskRun, 6));		
	}
private:
	virtual void Run(int nVal)
	{
		//运行队列里的任务。
		boost::system::error_code errorCode;
		m_ioService.run(errorCode);		
	}
private:
	//定义一个任务队列。
	boost::asio::io_service m_ioService;
	boost::asio::io_service::work m_Work;
	//定义一个线程组对象。
	boost::thread_group m_threadGroup;	

	//按顺序执行的对象。
	boost::asio::io_service::strand m_Strand;
};


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

	//设置最大的线程个数。
	threadBase.Start(3);
	threadBase.TestTask();
	Sleep(2000);
	std::cout << "TestStrandTask: " << std::endl;
	threadBase.TestStrandTask();
	Sleep(2000);
	threadBase.Stop();

	system("pause");

	return 0;
}

这是运行上面例子执行的结果:

TaskRun: 2

TaskRun: 4

TaskRun: 3

TaskRun: 1

TaskRun: 5

TaskRun: 6

TestStrandTask:

TaskRun: 1

TaskRun: 2

TaskRun: 3

TaskRun: 4

TaskRun: 5

TaskRun: 6

请按任意键继续. . .

从这个结果可以看到第一部份是无序执行的输出,最后一部份是有序执行。

抱歉!评论已关闭.