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; }
输出结果
使用C++11的lambda语法
Code
Code
注意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; } }