Roger Luo

超越梦想一起飞
  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

c++ concurrency serial 1: introduction

Posted on 2013-06-17 21:01  Roger Luo  阅读(435)  评论(0编辑  收藏  举报

platform: vs2012

#include <iostream>
#include <thread>
using namespace std;
void Fun()
{
	cout<<"Say hi from thread\n";
}
int main()
{
	std::thread th(Fun);
	cout<<"Say hi from main\n";
	th.join();
	return 0;
}

输出结果

Picture 2013-06-17 20_16_53

使用C++11的lambda语法

Code
创建多个线程运行
Code
Picture 2013-06-17 20_31_57

注意thread不具备copy constructor所以不能使用如下代码,否则会获取C2248错误

	for (int i = 0; i < 10; ++i)
	{
		thread th([i](){
			cout<<"Sai hi from thread "<<i<<endl;
		});
		workers.push_back(th);
	}

只能使用move semantics或者称为rvalue reference

Code

Code

Code

 

同一段代码在vs2012与gcc4.8.1中表现不一样

Code

前者是不管使用std::ref还是不使用都能编译通过且运行正确,后者是则必须使用std::ref才能编译通过,且运行不正确。

	typedef std::vector<std::string> StringVector;
	typedef StringVector::iterator StringVectorIter;

	enum EPackageNodeType
	{
		NodeUnKnown = 0,
		NodeNew,
		NodeDownloaded,
		NodeFinished,
		NodeFailed,
	};

	enum CapsuleAnalyzeResult
	{
		ANALYZE_OK = 0,
		INVALID_FILTER,
		INVALID_CLOSE,
		OTHER_ERROR
	};

	struct ISATZipFile
	{
		trwfUInt64	Size;	// compress size
		trwfUInt8	Tries;	// tries downloaad times
		trwfUInt8	State;	// donwload state
		std::string Name;	// name of rictable
		std::string	File;	// full path
		std::string	URL;	// full url
		ISATZipFile(): Size(0), Tries(0), State(NodeUnKnown){}
	};

	//typedef std::vector<ISATZipFile*, Framework::MFAlloc<ISATZipFile*> > ISATPackageVector;
	typedef std::vector<ISATZipFile*> ISATPackageVector;
	typedef ISATPackageVector::iterator ISATPackageVecotrIter;
	typedef ISATPackageVector* PISATPackageVector;

	inline void ReleaseISATPackageVector(ISATPackageVector& coll)
	{
		ISATPackageVecotrIter itEnd = coll.end();
		for (ISATPackageVecotrIter itPos = coll.begin(); itPos != itEnd; itPos++)
		{
			if (*itPos)
			{
				delete (*itPos);
				*itPos = nullptr;
			}
		}
		coll.clear();
	}

	inline void ReleaseISATPackageVector(PISATPackageVector& pcoll)
	{
		if (pcoll)
		{
			ReleaseISATPackageVector(*pcoll);
			delete pcoll;
			pcoll = nullptr;
		}
	}

	struct ISATIncrement
	{
		ISATPackageVector* Inserts;
		ISATPackageVector* Deletes;
		ISATPackageVector* Updates;
		ISATPackageVector* AliasInserts;
		ISATPackageVector* AliasDeletes;
		ISATPackageVector* AliasUpdates;
		ISATIncrement()
			: Inserts(new ISATPackageVector)
			, Deletes(new ISATPackageVector)
			, Updates(new ISATPackageVector)
			, AliasInserts(new ISATPackageVector)
			, AliasDeletes(new ISATPackageVector)
			, AliasUpdates(new ISATPackageVector)
		{}
		~ISATIncrement()
		{
			ReleaseISATPackageVector(Inserts);
			ReleaseISATPackageVector(Deletes);
			ReleaseISATPackageVector(Updates);
			ReleaseISATPackageVector(AliasInserts);
			ReleaseISATPackageVector(AliasDeletes);
			ReleaseISATPackageVector(AliasUpdates);
		}
	};
	//typedef std::vector<ISATIncrement*, Framework::MFAlloc<ISATIncrement*> > ISATIncrementBuilds;
	typedef std::vector<ISATIncrement*> ISATIncrementBuilds;
	typedef ISATIncrementBuilds::iterator ISATIncrementBuildsIter;
	typedef ISATIncrementBuilds * PISATIncrementBuilds;

	inline void ReleaseISATIncrementBuilds(PISATIncrementBuilds pcoll)
	{
		BOOST_FOREACH(ISATIncrement*& elem, *pcoll)
		{
			if (elem->Inserts) ReleaseISATPackageVector(*(elem->Inserts));
			if (elem->Deletes) ReleaseISATPackageVector(*(elem->Deletes));
			if (elem->Updates) ReleaseISATPackageVector(*(elem->Updates));
			if (elem->AliasInserts) ReleaseISATPackageVector(*(elem->AliasInserts));
			if (elem->AliasDeletes) ReleaseISATPackageVector(*(elem->AliasDeletes));
			if (elem->AliasUpdates) ReleaseISATPackageVector(*(elem->AliasUpdates));
		}
	}
	

	typedef struct _isatSummary
	{
		std::string strTimeStamp;
		ISATPackageVector* Image;
		ISATPackageVector* AliasImage;
		ISATIncrementBuilds* Increments;
		bool IsWeeklyBuild;
		_isatSummary():IsWeeklyBuild(false), Image(new ISATPackageVector), AliasImage(new ISATPackageVector),Increments(new ISATIncrementBuilds){
			Increments->reserve(7 * 24 * 60);
		}
		~_isatSummary(){
			ReleaseISATPackageVector(Image);
			ReleaseISATPackageVector(AliasImage);
			if (Increments)
			{
				delete Increments;
				Increments = nullptr;
			}
		}
	} ISATSummary;



#include "stdafx.h"
#include "SummaryParser.h"
#include <sstream>
#include <boost/regex.hpp>
#include <boost/foreach.hpp>
#include <boost/algorithm/string.hpp>
#include <ctime>
namespace IDH
{
	CSummaryParser::CSummaryParser(void)
		:	m_iCurPos(0)
		,	m_iTotalIncrement(0)
		,	m_pszFileRoot(0)
		,	m_pszURLRoot(0)
	{
		m_Elements.reserve(400000);
	}

	CSummaryParser::~CSummaryParser(void)
	{
	}

	int CSummaryParser::Parse(const char * pBuffer, const char * pszURLRoot, const char * pszFileRoot, ISATSummary* pSummary)
	{
		_ASSERT(pBuffer && pszURLRoot && pszFileRoot &&pSummary);
		if (!pBuffer || !pszURLRoot || !pszFileRoot ||!pSummary) return 1;

		m_pszFileRoot = pszFileRoot;
		m_pszURLRoot = pszURLRoot;

		if (0 != RetrieveElements(pBuffer))
		{
			cerr<<"Failed to retrieve elements from summary buffer."<<endl;
			return 1;
		}

		if (0 != ParseElements(pSummary))
		{
			cerr<<"Failed to parse elements from summary buffer."<<endl;
			return 1;
		}

		return 0;
	}

	int CSummaryParser::RetrieveElements(const char * pBuffer)
	{
		_ASSERT(pBuffer);
		PERFORMANCE_BEGIN
		clock_t _bgn = clock();
		static boost::regex rex("([^\\s=]*)", boost::regex::icase|boost::regex::perl);

		boost::cmatch what;
		
		boost::cregex_iterator itBgn = boost::make_regex_iterator(pBuffer, rex);
		boost::cregex_iterator itEnd;

		m_Elements.clear();
		m_iCurPos = 0;
		m_iTotalIncrement = 0;

		for_each(itBgn, itEnd, [this](const boost::cmatch& what){
			if (what[1].str().length() > 0)
			this->m_Elements.push_back((what[1].str()));
		});

		BOOST_FOREACH(std::string& elem, m_Elements)
		{
			boost::trim(elem);
		}
		cout<<__FUNCTION__<<"using "<<clock()-_bgn<<" mini seconds"<<endl;
		PERFORMANCE_END
		return 0;
	}

	int CSummaryParser::ParseElements(ISATSummary* pSummary)
	{
		int ret = 0;
		PERFORMANCE_BEGIN
		for (;m_iCurPos < m_Elements.size();)
		{
			if (boost::iequals(m_Elements[m_iCurPos], ISATGRABBERCONST::SUM_FULLBUILD) == true)
			{
				if (ParseFullBuildElement(*pSummary) != 0)
				{
					wcout<<L"Fail to parse [FullBuild]"<<endl;
					ret = 1;
					break;
				}
			}
			else if (boost::iequals(m_Elements[m_iCurPos], ISATGRABBERCONST::SUM_TABLES) == true)
			{
				if (ParseTablesElement(*(pSummary->Image)) != 0)
				{
					wcout<<L"Fail to parse [Tables]"<<endl;
					ret = 1;
					break;
				}
			}
			else if (boost::iequals(m_Elements[m_iCurPos], ISATGRABBERCONST::SUM_RAWALIASTABLES) == true)
			{
				if (ParseTablesElement(*(pSummary->AliasImage)) != 0)
				{
					wcout<<L"Fail to parse [RawAliasTables]"<<endl;
					ret = 1;
					break;
				}
			}
			else if (boost::iequals(m_Elements[m_iCurPos], ISATGRABBERCONST::SUM_INCREMENTALBUILD) == true)
			{
				if (ParseIncrementalBuildElement(*pSummary) != 0)
				{
					wcout<<L"Fail to parse [IncrementalBuild]"<<endl;
					return 1;
				}
			}
			else if (boost::istarts_with(m_Elements[m_iCurPos], ISATGRABBERCONST::SUM_INCREMENTALBUILDEACH) == true)
			{
				if (ParseIncrementalBuildEachElement(*pSummary) != 0)
				{
					wcout<<L"Fail to parse [IncrementalBuild_Each]"<<endl;
					ret = 1;
					break;
				}
			}
			else
			{
				cerr<<"Detect unknown node: "<<m_Elements[m_iCurPos]<<": at "<<m_iCurPos<<endl;
				m_iCurPos++;
			}
			
		}
		PERFORMANCE_END
		return ret;
	}

	int CSummaryParser::ParseFullBuildElement(ISATSummary& full)
	{
		if (m_iCurPos + ISATGRABBERCONST::SUM_FULLBUILDLENGTH >= m_Elements.size())
			return 1;
		if (boost::iequals(m_Elements[++m_iCurPos], ISATGRABBERCONST::SUM_LATEST) == false)
			return 1;

		if (full.strTimeStamp.compare(m_Elements[++m_iCurPos]) != 0)
		{
			// new full build
			ReleaseISATPackageVector(*(full.Image));
			ReleaseISATPackageVector(*(full.AliasImage));
			ReleaseISATIncrementBuilds(full.Increments);
			full.strTimeStamp = m_Elements[m_iCurPos];
			full.IsWeeklyBuild = true;
		}

		m_iCurPos++;
		return 0;
	}

	int CSummaryParser::ParseTablesElement(ISATPackageVector& coll)
	{
		if (m_iCurPos + ISATGRABBERCONST::SUM_TABLESLENGTH >= m_Elements.size())
			return 1;
		if (boost::iequals(m_Elements[++m_iCurPos], ISATGRABBERCONST::SUM_NUMBEROFTABLES) == false)
			return 1;
		int number = atoi(m_Elements[++m_iCurPos].c_str());

		// get all tables
		for (int i = 1; i <= number && m_iCurPos + ISATGRABBERCONST::SUM_GERNERICLENGTH < m_Elements.size(); i++)
		{
			int numFile = 0, numSize = 0;
			numFile = atoi(m_Elements[++m_iCurPos].c_str() + strlen(ISATGRABBERCONST::SUM_TABLE));
			std::string name = m_Elements[++m_iCurPos];
			numSize = atoi(m_Elements[++m_iCurPos].c_str() + strlen(ISATGRABBERCONST::SUM_CMPSIZETABLE));
			int size = atoi(m_Elements[++m_iCurPos].c_str());
			if (numFile != numSize ||
				numFile != i)
				return 1;
			ReplaceFileName(name, ISATGRABBERCONST::SUM_FILE_TXT, ISATGRABBERCONST::SUM_FILE_Z);
			if (coll.size() < i)
			{
				ISATZipFile* ptable = new ISATZipFile;
				ptable->State = NodeNew;
				ptable->Name = name;
				ptable->Size = size;
				coll.push_back(ptable);
			}
			else
			{
				if (coll[i-1]->Size != size ||
					boost::iequals(coll[i-1]->Name, name) == false)
				{
				}
			}
		}
		m_iCurPos++;
		return 0;
	}

	int CSummaryParser::ParseIncrementalBuildElement(ISATSummary& full)
	{
		if (m_iCurPos + ISATGRABBERCONST::SUM_INCREMENTALBUILDLENGTH > m_Elements.size())
			return 1;
		if (boost::iequals(m_Elements[++m_iCurPos], ISATGRABBERCONST::SUM_NUMBEROFBUILDS) == false)
			return 1;

		m_iTotalIncrement = atoi(m_Elements[++m_iCurPos].c_str());
		m_iCurPos++;
		return 0;
	}

	int CSummaryParser::ParseIncrementalBuildEachElement(ISATSummary& full)
	{
		int iIncrementtalNumber = atoi(m_Elements[m_iCurPos].c_str() + strlen(ISATGRABBERCONST::SUM_INCREMENTALBUILDEACH));
		if (iIncrementtalNumber > m_iTotalIncrement)
			return 1;
		if (iIncrementtalNumber > full.Increments->size())
			full.Increments->push_back(new ISATIncrement());
		while (++m_iCurPos < m_Elements.size() && m_Elements[m_iCurPos][0] != ISATGRABBERCONST::SUM_PREFIX_PATTERN)
		{
			if (boost::istarts_with(m_Elements[m_iCurPos], ISATGRABBERCONST::SUM_NUMBEROFUPDATETABLES) == true)
			{
				if (ParseIncremental(ISATGRABBERCONST::SUM_UPDATETABLE, ISATGRABBERCONST::SUM_CMPSIZEUPDATETABLE, (*(full.Increments))[iIncrementtalNumber-1]->Updates) != 0)
				{
					wcout<<L"Fail to parse [UPDATETABLE]"<<endl;
					return 1;
				}
			}
			else if (boost::istarts_with(m_Elements[m_iCurPos], ISATGRABBERCONST::SUM_NUMBEROFADDTABLES) == true)
			{
				if (ParseIncremental(ISATGRABBERCONST::SUM_ADDTABLE, ISATGRABBERCONST::SUM_CMPSIZEADDTABLE, (*(full.Increments))[iIncrementtalNumber-1]->Inserts) != 0)
				{
					wcout<<L"Fail to parse [ADDTABLE]"<<endl;
					return 1;
				}
			}
			else if (boost::istarts_with(m_Elements[m_iCurPos], ISATGRABBERCONST::SUM_NUMBEROFDELETETABLES) == true)
			{
				if (ParseIncremental(ISATGRABBERCONST::SUM_DELETETABLE, ISATGRABBERCONST::SUM_CMPSIZEDELETETABLE, (*(full.Increments))[iIncrementtalNumber-1]->Deletes) != 0)
				{
					wcout<<L"Fail to parse [DELETETABLE]"<<endl;
					return 1;
				}
			}
			else if (boost::istarts_with(m_Elements[m_iCurPos], ISATGRABBERCONST::SUM_NUMBEROFRAWALIASUPDATETABLES) == true)
			{
				if (ParseIncremental(ISATGRABBERCONST::SUM_RAWALIASUPDATETABLE, ISATGRABBERCONST::SUM_CMPSIZERAWALIASUPDATETABLE, (*(full.Increments))[iIncrementtalNumber-1]->AliasUpdates) != 0)
				{
					wcout<<L"Fail to parse [RAWALIASUPDATETABLE]"<<endl;
					return 1;
				}
			}
			else if (boost::istarts_with(m_Elements[m_iCurPos], ISATGRABBERCONST::SUM_NUMBEROFRAWALIASADDTABLES) == true)
			{
				if (ParseIncremental(ISATGRABBERCONST::SUM_RAWALIASADDTABLE, ISATGRABBERCONST::SUM_CMPSIZERAWALIASADDTABLE, (*(full.Increments))[iIncrementtalNumber-1]->AliasInserts) != 0)
				{
					wcout<<L"Fail to parse [RAWALIASADDTABLE]"<<endl;
					return 1;
				}
			}
			else if (boost::istarts_with(m_Elements[m_iCurPos], ISATGRABBERCONST::SUM_NUMBEROFRAWALIASDELETETABLES) == true)
			{
				if (ParseIncremental(ISATGRABBERCONST::SUM_RAWALIASDELETETABLE, ISATGRABBERCONST::SUM_CMPSIZERAWALIASDELETETABLE, (*(full.Increments))[iIncrementtalNumber-1]->AliasDeletes) != 0)
				{
					wcout<<L"Fail to parse [RAWALIASDELETETABLE]"<<endl;
					return 1;
				}
			}
			else
			{
				cerr<<"Invalide line:"<<m_Elements[m_iCurPos]<<endl;
			}
		}
		return 0;
	}

	int CSummaryParser::ParseIncremental(std::string namepattern, std::string sizepattern, PISATPackageVector& pcoll)
	{
		if (++m_iCurPos >= m_Elements.size())
			return 1;
		int number = atoi(m_Elements[m_iCurPos].c_str());

		if (number == 0)
			return 0;

		for (int i = 1; i <= number && m_iCurPos + ISATGRABBERCONST::SUM_GERNERICLENGTH < m_Elements.size(); i++)
		{
			int numFile = 0, numSize = 0;
			numFile = atoi(m_Elements[++m_iCurPos].c_str() + namepattern.size());
			std::string name = m_Elements[++m_iCurPos];
			numSize = atoi(m_Elements[++m_iCurPos].c_str() + sizepattern.size());
			int size = atoi(m_Elements[++m_iCurPos].c_str());
			if (numFile != numSize ||
				numFile != i)
				return 1;
			ReplaceFileName(name, ISATGRABBERCONST::SUM_FILE_TXT, ISATGRABBERCONST::SUM_FILE_Z);
			if (pcoll->size() < i)
			{
				ISATZipFile * pnode = new ISATZipFile;
				pnode->Name = name;
				pnode->Size = size;
				pnode->State = NodeNew;
				pcoll->push_back(pnode);
			}
			else
			{
				if ((*pcoll)[i-1]->Size != size ||
					boost::iequals((*pcoll)[i-1]->Name, name) == false)
					return 1;
			}
		}
		
		return 0;
	}

	void CSummaryParser::ReplaceFileName(std::string& inout, const std::string& s1, const std::string& s2)
	{
		boost::to_lower(inout);
		size_t pos = inout.rfind(s1);
		if (pos != std::string::npos)
			inout.replace(pos, s1.length(), s2);
	}

	int CSummaryParser::RetrieveElements2(string& buffer)
	{
		clock_t _bgn=clock();
		m_Elements.clear();
		list<boost::iterator_range<string::iterator> > l;
		boost::split(l, buffer, boost::is_any_of("\n="), boost::token_compress_on);
		for (auto pos = l.begin(); pos != l.end(); pos++)
		{
			m_Elements.push_back(string(pos->begin(), pos->end()));
		}
		cout<<__FUNCTION__<<"using "<<clock()-_bgn<<" mini seconds"<<endl;
		return 0;
	}
}