Files
RepoMain/ZCppMain/ZCProcess.H

1775 lines
68 KiB
C++
Raw Normal View History


#ifndef __ZCPPMAIN__PROCESS_H__
#define __ZCPPMAIN__PROCESS_H__
#include <string>
#include "ZCppMain/ZMainHead.H"
#ifdef _DEBUG_CEXCEPT_EXIT_
#include <iostream>
#endif
namespace ZNsMain
{
namespace ZNsIFace
{
class ZISyncEasy
{
public:
bool Lock (){return false;}
bool UnLock(){return false;}
public:
};/*
class ZISyncEasy*/
}/*
namespace ZNsIFace*/
template<typename TString> class ZtCExceptSync : public ZNsMain::ZCExceptBase
{
private:
int mi_ErrNum ;
int mi_LineNum ;
TString mo_FileName;
public :
ZtCExceptSync(int AI_LineNum=0): mi_LineNum(AI_LineNum){mi_ErrNum=0;}
ZtCExceptSync(const char* AP_FileName, int AI_LineNum=0, int AI_ErrNum=0): mi_LineNum(AI_LineNum)
{
mi_ErrNum =AI_ErrNum ;
mo_FileName=AP_FileName;
#ifdef _DEBUG_CEXCEPT_EXIT_
std::cerr<<"★★ FileName="<<AP_FileName<<", LineNum="<<AI_LineNum<<", AI_ErrNum="<<AI_ErrNum<<std::endl; ::exit(0);
#endif //_DEBUG_CEXCEPT_EXIT_
}/*
ZtCExceptSync(const char* AP_FileName, int AI_LineNum=0, int AI_ErrNum=0)*/
int GetLineNum() const{return mi_LineNum;}
int GetErrNum () const{return mi_ErrNum ;}
const TString& GetFileName() const
{
return mo_FileName;
}/*
const TString& GetFileName() const*/
public:
};/*
template<typename TString> class ZtCExceptSync : public ZNsMain::ZCExceptBase*/
typedef ZtCExceptSync<std::string> ZCExceptSync;
/*///////////////////////////////////////////////////////////////////////////////////////
CWorkPool.H 릿 ,
object .
( Easy 릿)
ZtCSyncEasyValid<> CSyncEasyEmpty_T<> .
///////////////////////////////////////////////////////////////////////////////////////*/
template<typename TSyncEasy> class ZtCSyncEasyValid
{
public :
enum{EUseLockObj=1};
protected:
TSyncEasy mo_CSyncEasy;
public :
void Lock (){mo_CSyncEasy.Lock ();}
void UnLock(){mo_CSyncEasy.UnLock();}
public :
};/*
template<typename TSyncEasy> class ZtCSyncEasyValid */
template<typename TSyncEasy=ZNsMain::ZCEmpty> class CSyncEasyEmpty_T
{
public:
enum{EUseLockObj=0};
public:
void Lock (){}
void UnLock(){}
public:
};/*
template<typename TSyncEasy=ZNsMain::ZCEmpty> class CSyncEasyEmpty_T */
}/*
namespace ZNsMain*/
#ifdef _WIN
#include "ZCppMain/ZCProcess_Win.H"
#elif defined(__linux__)
#include "ZCppMain/ZCProcess_Linux.H"
#else
#include "ZCppMain/ZCProcess_Linux.H"
#endif
namespace ZNsMain
{
/*/////////////////////////////////////////////////////////////
class ZtCSyncCount lock
.
.
0 .
lock lock 1
lock lock 1 .
/////////////////////////////////////////////////////////////*/
template< typename TSemaphore=ZNsMain::ZCThreadSemaphore
>
class ZtCSyncCount : public TSemaphore ///////////////////
{
protected:
int mi_LockCount;
public :
ZtCSyncCount(int AI_LockCount=0) : TSemaphore()
{
mi_LockCount=AI_LockCount;
}/*
ZtCSyncCount(int AI_LockCount=0)*/
bool LockCount()
{
--mi_LockCount; return this->TSemaphore::Lock();
}/*
bool LockCount()*/
template<typename TSyncExec>
bool LockCount(TSyncExec& AR_CSyncExec)
{
--mi_LockCount;
AR_CSyncExec.UnLock();
{
if(this->TSemaphore::Lock()==false) return false;
}
AR_CSyncExec.Lock();
return false;
}/*
template<typename TSyncExec>
bool LockCount(TSyncExec& AR_CSyncExec) */
// cf) linux 의 semctl(), semop() 계열의 세마포어에서는 LockTime() 함수가 없다.
template<typename TSyncExec>
int LockCountTime(TSyncExec& AR_CSyncExec, int AI_TimeOutMili)
{
int VI_LockCode=ZNsMain::ZNsEnum::ZEThread_OK;
--mi_LockCount;
AR_CSyncExec.UnLock();
{
VI_LockCode=this->TSemaphore::LockTime(AI_TimeOutMili);
}
AR_CSyncExec.Lock();
if(VI_LockCode==ZNsMain::ZNsEnum::ZEThread_TimeOut)
{
++mi_LockCount;
}/*
if(VI_LockCode==ZNsMain::ZNsEnum::ZEThread_TimeOut)*/
return VI_LockCode;
}/*
template<typename TSyncExec>
int LockCountTime(TSyncExec& AR_CSyncExec, int AI_TimeOutMili) */
bool UnLockCount()
{
++mi_LockCount; return this->TSemaphore::UnLock();
}/*
bool UnLockCount()*/
int GetLockCount() const
{
return mi_LockCount;
}/*
int GetLockCount() const*/
public:
};/*
template< typename TSemaphore=ZNsMain::ZCThreadSemaphore
>
class ZtCSyncCount : public TSemaphore /////////////////*/
/*////////////////////////////////////////////////////////////
class ZtCSyncCountRef ZtCSyncCount ,
object .
////////////////////////////////////////////////////////////*/
template< typename TSemaphore=ZNsMain::ZCThreadSemaphore
>
class ZtCSyncCountRef ////////////////////////////////////
{
private :
ZtCSyncCountRef(const ZtCSyncCountRef& rhs)
{
}/*
ZtCSyncCountRef(const ZtCSyncCountRef& rhs)*/
ZtCSyncCountRef& operator=(const ZtCSyncCountRef& rhs)
{
return *this;
}/*
ZtCSyncCountRef& operator=(const ZtCSyncCountRef& rhs)*/
protected:
TSemaphore& mr_CSemaphore;
int mi_LockCount ;
public :
ZtCSyncCountRef(TSemaphore& AR_CSemaphore, int AI_LockCount) :
mr_CSemaphore(AR_CSemaphore)
{
mi_LockCount=AI_LockCount;
}/*
ZtCSyncCountRef(TSemaphore& AR_CSemaphore, int AI_LockCount)*/
bool LockCount()
{
--mi_LockCount; return mr_CSemaphore.Lock();
}/*
bool LockCount()*/
template<typename TSyncExec>
bool LockCount(TSyncExec& AR_CSyncExec)
{
--mi_LockCount;
AR_CSyncExec.UnLock();
{
if(mr_CSemaphore.Lock()==false) return false;
}
AR_CSyncExec.Lock();
return true;
}/*
template<typename TSyncExec>
bool LockCount(TSyncExec& AR_CSyncExec) */
template<typename TSyncExec>
int LockCountTime(TSyncExec& AR_CSyncExec, int AI_TimeOutMili)
{
int VI_LockCode=ZNsMain::ZNsEnum::ZEThread_OK;
--mi_LockCount;
AR_CSyncExec.UnLock();
{
VI_LockCode=mr_CSemaphore.LockTime(AI_TimeOutMili);
}
AR_CSyncExec.Lock();
if(VI_LockCode==ZNsMain::ZNsEnum::ZEThread_TimeOut)
{
++mi_LockCount;
}/*
if(VI_LockCode==ZNsMain::ZNsEnum::ZEThread_TimeOut)*/
return VI_LockCode;
}/*
template<typename TSyncExec>
int LockCountTime(TSyncExec& AR_CSyncExec, int AI_TimeOutMili) */
bool UnLockCount()
{
++mi_LockCount; return mr_CSemaphore.UnLock();
}/*
bool UnLockCount()*/
int GetLockCount() const
{
return mi_LockCount;
}/*
int GetLockCount() const*/
public:
};/*
template< typename TSemaphore=ZNsMain::ZCThreadSemaphore
>
class ZtCSyncCountRef //////////////////////////////////*/
/*///////////////////////////////////////////////////////////////////////////////////
ZtCThreadEx<> 릿 ZNsMain::ZtCThread<>
, Exec() .
Init(), Fini() .
void Exec(THelpKey AR_HelpKey)
Init(AR_HelpKey), Fini(AR_HelpKey), Exec(AR_HelpKey)
public .
ZtCThreadEx<>::ZtCHelpKeyParam<> 릿 friend
.
cf) template <class S> template <class U> friend class A<S>::B;
2 릿 Exec2(THelpKey1, THelpKey2) Exec
Exec(THelpKey1,THelpKey2) .
ZtCThreadEx<> 릿 , Exec(THelpKey1)
, ''
Init(THelpKey1), Fini(THelpKey1)
, .
ZtCThreadEx<>::Init(THelpKey1)
ZtCThreadEx<>::Fini(THelpKey1)
(?) .
-- 2010-02-21 20:05:00
Exec2(THelpKey1,THelpKey2) ,
Init2(THelpKey1,THelpKey2)
Fini2(THelpKey1,THelpKey2) .
CWorkPool.H
CTypeCtrlSnglAllocWork_T<>::CSnglAllocWork::Init2(~)
CTypeCtrlSnglAllocWork_T<>::CSnglAllocWork::Fini2(~)
this->CThreadBase::template Init <THelpKey1, THelpKey2>(AR_HelpKey1, AR_HelpKey2)
this->CThreadBase::template Fini <THelpKey1, THelpKey2>(AR_HelpKey1, AR_HelpKey2)
,
this->CThreadBase::template Init2<THelpKey1, THelpKey2>(AR_HelpKey1, AR_HelpKey2)
this->CThreadBase::template Fini2<THelpKey1, THelpKey2>(AR_HelpKey1, AR_HelpKey2)
. 2~3 .
-- 2011-02-03 14:34:00
///////////////////////////////////////////////////////////////////////////////////*/
template< typename TDerive, typename TThread=ZtCThread<>
>
class ZtCThreadEx : public TThread ///////////////////////
{
public :
typedef ZtCThreadEx ZCThreadEx;
typedef TDerive ZCDerive ;
protected:
template<typename THelpKey> class ZtCHelpKeyParam
{
private:
friend class ZtCThreadEx;
private:
THelpKey mr_HelpKey;
ZCDerive* mp_CDerive;
private:
ZtCHelpKeyParam(THelpKey AR_HelpKey, ZCDerive& AR_CDerive) :
mr_HelpKey(AR_HelpKey)
{
mp_CDerive = &AR_CDerive;
}/*
ZtCHelpKeyParam(THelpKey AR_HelpKey, ZCDerive& AR_CDerive)*/
/*////////////////////////////////////////////////////////////////////////
(*mp_CDerive) Init,Exec,Fini 릿 .
"->template" 릿 .
-- 2009-08-01 20:05:00
////////////////////////////////////////////////////////////////////////*/
#if(_CODE_OLD_)
void Init(){mp_CDerive->template Init<THelpKey>(mr_HelpKey);}
void Exec(){mp_CDerive->template Exec<THelpKey>(mr_HelpKey);}
void Fini(){mp_CDerive->template Fini<THelpKey>(mr_HelpKey);}
#else
void Init(){mp_CDerive->Init(mr_HelpKey);}
void Exec(){mp_CDerive->Exec(mr_HelpKey);}
void Fini(){mp_CDerive->Fini(mr_HelpKey);}
#endif
private:
};/*
template<typename THelpKey> class ZtCHelpKeyParam */
template<typename THelpKey1, typename THelpKey2> class ZtCHelpKeyParam2
{
private:
friend class ZtCThreadEx;
private:
THelpKey1 mr_HelpKey1;
THelpKey2 mr_HelpKey2;
ZCDerive* mp_CDerive ;
private:
ZtCHelpKeyParam2(THelpKey1 AR_HelpKey1, THelpKey2 AR_HelpKey2, ZCDerive& AR_CDerive) :
mr_HelpKey1(AR_HelpKey1), mr_HelpKey2(AR_HelpKey2)
{
mp_CDerive=&AR_CDerive;
}/*
ZtCHelpKeyParam2(THelpKey1 AR_HelpKey1, THelpKey2 AR_HelpKey2, ZCDerive& AR_CDerive)*/
/*////////////////////////////////////////////////////////////////////////
(*mp_CDerive) Init, Exec, Fini 릿 .
"->template" 릿 .
-- 2009-08-01 20:05:00
////////////////////////////////////////////////////////////////////////*/
#if(_CODE_OLD_)
void Init2(){mp_CDerive->template Init2<THelpKey1, THelpKey2>(mr_HelpKey1, mr_HelpKey2);}
void Exec2(){mp_CDerive->template Exec2<THelpKey1, THelpKey2>(mr_HelpKey1, mr_HelpKey2);}
void Fini2(){mp_CDerive->template Fini2<THelpKey1, THelpKey2>(mr_HelpKey1, mr_HelpKey2);}
#else
void Init(){mp_CDerive->Init(mr_HelpKey1, mr_HelpKey2);}
void Exec(){mp_CDerive->Exec(mr_HelpKey1, mr_HelpKey2);}
void Fini(){mp_CDerive->Fini(mr_HelpKey1, mr_HelpKey2);}
#endif
private:
};/*
template<typename THelpKey1, typename THelpKey2> class ZtCHelpKeyParam2 */
template< typename THelpKey1, typename THelpKey2, typename THelpKey3
>
class ZtCHelpKeyParam3 ///////////////////////////////////////////////
{
private:
friend class ZtCThreadEx;
private:
THelpKey1 mr_HelpKey1;
THelpKey2 mr_HelpKey2;
THelpKey3 mr_HelpKey3;
ZCDerive* mp_CDerive ;
private:
ZtCHelpKeyParam3 /*:::::::::::::::::::::::::::::::::::::::::::::::::::::*/
(
THelpKey1 AR_HelpKey1, THelpKey2 AR_HelpKey2,
THelpKey3 AR_HelpKey3, ZCDerive& AR_CDerive
) :
mr_HelpKey1(AR_HelpKey1), mr_HelpKey2(AR_HelpKey2), mr_HelpKey3(AR_HelpKey3)
{
mp_CDerive=&AR_CDerive;
}/*
ZtCHelpKeyParam3(THelpKey1 AR_HelpKey1, THelpKey2 AR_HelpKey2, THelpKey3 AR_HelpKey3, ZCDerive& AR_CDerive)*/
/*////////////////////////////////////////////////////////////////////////
(*mp_CDerive) Init, Exec, Fini 릿 .
"->template" 릿 .
-- 2009-08-01 20:05:00
////////////////////////////////////////////////////////////////////////*/
#if(_CODE_OLD_)
void Init3(){mp_CDerive->template Init3<THelpKey1, THelpKey2, THelpKey3>(mr_HelpKey1, mr_HelpKey2, mr_HelpKey3);}
void Exec3(){mp_CDerive->template Exec3<THelpKey1, THelpKey2, THelpKey3>(mr_HelpKey1, mr_HelpKey2, mr_HelpKey3);}
void Fini3(){mp_CDerive->template Fini3<THelpKey1, THelpKey2, THelpKey3>(mr_HelpKey1, mr_HelpKey2, mr_HelpKey3);}
#else
void Init(){mp_CDerive->Init(mr_HelpKey1, mr_HelpKey2, mr_HelpKey3);}
void Exec(){mp_CDerive->Exec(mr_HelpKey1, mr_HelpKey2, mr_HelpKey3);}
void Fini(){mp_CDerive->Fini(mr_HelpKey1, mr_HelpKey2, mr_HelpKey3);}
#endif
public:
};/*
template< typename THelpKey1, typename THelpKey2, typename THelpKey3
>
class ZtCHelpKeyParam3 /////////////////////////////////////////////*/
/*protected:*/
protected:
_VT_ void Init()
{
this->TThread::Detach(); // linux 에서는 아주 중요한 코드이다.
#ifdef _DEBUG
std::cout<<"ZCThreadEx::Init()"<<std::endl;
#endif //_DEBUG
}/*
_VT_ void Init()*/
template<typename THelpKey> _VT_ void Init(THelpKey)
{
this->TThread::Detach(); // linux 에서는 아주 중요한 코드이다.
#ifdef _DEBUG
std::cout<<"# ZCThreadEx::Init(THelpKey), THelpKey typename="<<typeid(THelpKey).name()<<std::endl;
#endif //_DEBUG
}/*
template<typename THelpKey> _VT_ void Init(THelpKey)*/
template<typename THelpKey1, typename THelpKey2> _VT_ void Init(THelpKey1, THelpKey2)
{
this->TThread::Detach(); // linux 에서는 아주 중요한 코드이다.
#ifdef _DEBUG
std::cout<<"## ZCThreadEx::Init(THelpKey1, THelpKey2), "
"THelpKey1 typename="<<typeid(THelpKey1).name()<<", "
"THelpKey2 typename="<<typeid(THelpKey2).name()<<std::endl;
#endif //_DEBUG
}/*
template<typename THelpKey1, typename THelpKey2> _VT_ void Init(THelpKey1, THelpKey2)*/
template< typename THelpKey1, typename THelpKey2, typename THelpKey3
>
_VT_ void Init(THelpKey1, THelpKey2, THelpKey3) /*##################*/
{
this->TThread::Detach(); // linux 에서는 아주 중요한 코드이다.
#ifdef _DEBUG
std::cout<<"## ZCThreadEx::Init(THelpKey1, THelpKey2, THelpKey3), "
"THelpKey1 typename="<<typeid(THelpKey1).name()<<", "
"THelpKey2 typename="<<typeid(THelpKey2).name()<<", "
"THelpKey3 typename="<<typeid(THelpKey3).name()<<std::endl;
#endif //_DEBUG
}/*
template< typename THelpKey1, typename THelpKey2, typename THelpKey3
>
_VT_ void Init(THelpKey1, THelpKey2, THelpKey3) ####################*/
_VT_ void Exec()
{
#ifdef _DEBUG
std::cout<<"ZCThreadEx::Exec()"<<std::endl;
#endif //_DEBUG
}/*
_VT_ void Exec()*/
template<typename THelpKey> _VT_ void Exec(THelpKey)
{
#ifdef _DEBUG
std::cout<<"# ZCThreadEx::Exec(THelpKey), THelpKey typename="<<typeid(THelpKey).name()<<std::endl;
#endif //_DEBUG
}/*
template<typename THelpKey> _VT_ void Exec(THelpKey)*/
template<typename THelpKey1, typename THelpKey2> _VT_ void Exec(THelpKey1, THelpKey2)
{
#ifdef _DEBUG
std::cout<<"## ZCThreadEx::Exec(THelpKey1, THelpKey2), "
"THelpKey1 typename="<<typeid(THelpKey1).name()<<", "
"THelpKey2 typename="<<typeid(THelpKey2).name()<<std::endl;
#endif //_DEBUG
}/*
template<typename THelpKey1, typename THelpKey2> _VT_ void Exec(THelpKey1 AR_HelpKey1,THelpKey2 AR_HelpKey2)*/
template<typename THelpKey1, typename THelpKey2, typename THelpKey3>
_VT_ void Exec(THelpKey1 AR_HelpKey1,THelpKey2 AR_HelpKey2,THelpKey3 AR_HelpKey3)
{
#ifdef _DEBUG
std::cout<<"## ZCThreadEx::Exec(THelpKey1, THelpKey2, THelpKey3), "
"THelpKey1 typename="<<typeid(THelpKey1).name()<<", "
"THelpKey2 typename="<<typeid(THelpKey2).name()<<", "
"THelpKey3 typename="<<typeid(THelpKey3).name()<<std::endl;
#endif //_DEBUG
}/*
template<typename THelpKey1, typename THelpKey2, typename THelpKey3>
_VT_ void Exec(THelpKey1 AR_HelpKey1,THelpKey2 AR_HelpKey2,THelpKey3 AR_HelpKey3) */
_VT_ void Fini()
{
#ifdef _DEBUG
std::cout<<"ZCThreadEx::Fini()"<<std::endl;
#endif //_DEBUG
}/*
_VT_ void Fini()*/
template<typename THelpKey> _VT_ void Fini(THelpKey)
{
#ifdef _DEBUG
std::cout<<"# ZCThreadEx::Fini(THelpKey), THelpKey typename="<<typeid(THelpKey).name()<<std::endl;
#endif //_DEBUG
}/*
template<typename THelpKey> _VT_ void Fini(THelpKey) */
template<typename THelpKey1, typename THelpKey2> _VT_ void Fini(THelpKey1, THelpKey2)
{
#ifdef _DEBUG
std::cout<<"## ZCThreadEx::Fini(THelpKey1, THelpKey2), "
"THelpKey1 typename="<<typeid(THelpKey1).name()<<", "
"THelpKey2 typename="<<typeid(THelpKey2).name()<<std::endl;
#endif //_DEBUG
}/*
template<typename THelpKey1, typename THelpKey2> _VT_ void Fini(THelpKey1, THelpKey2)*/
template< typename THelpKey1, typename THelpKey2, typename THelpKey3
>
_VT_ void Fini(THelpKey1, THelpKey2, THelpKey3) //////////////////////
{
#ifdef _DEBUG
std::cout<<"## ZCThreadEx::Fini(THelpKey1, THelpKey2, THelpKey3), "
"THelpKey1 typename="<<typeid(THelpKey1).name()<<", "
"THelpKey2 typename="<<typeid(THelpKey2).name()<<", "
"THelpKey3 typename="<<typeid(THelpKey3).name()<<std::endl;
#endif //_DEBUG
}/*
template< typename THelpKey1, typename THelpKey2, typename THelpKey3
>
_VT_ void Fini(THelpKey1, THelpKey2, THelpKey3) ////////////////////*/
static _THREAD_RETURN_ ThreadFunc(void* AP_Void)
{
ZCDerive* VP_CDerive = (ZCDerive*)AP_Void;
VP_CDerive->Init();
VP_CDerive->Exec();
VP_CDerive->Fini(); return 0; ///////////
}/*
static _THREAD_RETURN_ ThreadFunc(void* AP_Void)*/
template<typename THelpKey>
static _THREAD_RETURN_ ThreadFuncHelpKey(void* AP_Void)
{
typedef ZtCHelpKeyParam<THelpKey> ZCHelpKeyParam;
ZCHelpKeyParam* VP_CHelpKeyParam = (ZCHelpKeyParam*)AP_Void;
VP_CHelpKeyParam->Init();
VP_CHelpKeyParam->Exec();
VP_CHelpKeyParam->Fini(); delete VP_CHelpKeyParam; return 0;
}/*
template<typename THelpKey>
static _THREAD_RETURN_ ThreadFuncHelpKey(void* AP_Void) */
template<typename THelpKey1, typename THelpKey2>
static _THREAD_RETURN_ ThreadFuncHelpKey2(void* AP_Void)
{
typedef ZtCHelpKeyParam2<THelpKey1, THelpKey2> CHelpKeyParam2;
CHelpKeyParam2* VP_CHelpKeyParam2 = (CHelpKeyParam2*)AP_Void ;
#if(_CODE_OLD_)
VP_CHelpKeyParam2->Init2();
VP_CHelpKeyParam2->Exec2();
VP_CHelpKeyParam2->Fini2();
#else
VP_CHelpKeyParam2->Init ();
VP_CHelpKeyParam2->Exec ();
VP_CHelpKeyParam2->Fini ();
#endif
delete VP_CHelpKeyParam2; return 0;
}/*
template<typename THelpKey1, typename THelpKey2>
static _THREAD_RETURN_ ThreadFuncHelpKey2(void* AP_Void) */
template< typename THelpKey1, typename THelpKey2, typename THelpKey3
>
static _THREAD_RETURN_ ThreadFuncHelpKey3(void* AP_Void) /////////////
{
typedef ZtCHelpKeyParam3
<THelpKey1, THelpKey2, THelpKey3> CHelpKeyParam3;
CHelpKeyParam3* VP_CHelpKeyParam3 = (CHelpKeyParam3*)AP_Void;
#if(_CODE_OLD_)
VP_CHelpKeyParam3->Init3();
VP_CHelpKeyParam3->Exec3();
VP_CHelpKeyParam3->Fini3();
#else
VP_CHelpKeyParam3->Init ();
VP_CHelpKeyParam3->Exec ();
VP_CHelpKeyParam3->Fini ();
#endif
delete VP_CHelpKeyParam3; return 0;
}/*
template< typename THelpKey1, typename THelpKey2, typename THelpKey3
>
static _THREAD_RETURN_ ThreadFuncHelpKey3(void* AP_Void) ///////////*/
ZCDerive* GetCDerivePtr()
{
return static_cast<ZCDerive*>(this);
}/*
ZCDerive* GetCDerivePtr()*/
/*protected:*/
public :
ZtCThreadEx()
{
_DEBUG_REENTRANT_CHECK_
}/*
ZtCThreadEx()*/
ZtCThreadEx(const ZtCThreadEx& rhs)
{
_DEBUG_REENTRANT_CHECK_
(TThread&)(*this)=(TThread&)rhs;
}/*
ZtCThreadEx(const ZtCThreadEx& rhs)*/
ZtCThreadEx& operator=(const ZtCThreadEx& rhs)
{
return *this; // nothig to do
}/*
ZtCThreadEx& operator=(const ZtCThreadEx& rhs)*/
virtual ~ZtCThreadEx(){}
bool Make()
{
return this->TThread::Make(ThreadFunc, GetCDerivePtr());
}/*
bool Make()*/
template<typename THelpKey> bool Make(THelpKey AR_HelpKey)
{
typedef ZNsMain::ZtCCheckRef<THelpKey> ZCCheckRef ;
typedef typename ZCCheckRef::TypeData TypeData ;
typedef ZtCHelpKeyParam<TypeData> ZCHelpKeyParam;
ZCHelpKeyParam* VP_CHelpKeyParam = new ZCHelpKeyParam
(
ZCCheckRef::PassData(AR_HelpKey), *GetCDerivePtr()
);
/*:::::::::::::::::::::::::::::::::::::::::::::::::::*/
return this->TThread::Make(
&ZtCThreadEx::template ThreadFuncHelpKey
<
TypeData
> ,
VP_CHelpKeyParam
/*/////////*/ ); ///////////////////////////////////////
}/*
template<typename THelpKey> bool Make(THelpKey AR_HelpKey) */
template<typename THelpKey1, typename THelpKey2>
bool Make(THelpKey1 AR_HelpKey1, THelpKey2 AR_HelpKey2)
{
typedef ZNsMain::ZtCCheckRef<THelpKey1> ZCCheckRef1;
typedef ZNsMain::ZtCCheckRef<THelpKey2> ZCCheckRef2;
typedef typename ZCCheckRef1::TypeData TypeData1 ;
typedef typename ZCCheckRef2::TypeData TypeData2 ;
typedef ZtCHelpKeyParam2<TypeData1, TypeData2> ZCHelpKeyParam;
ZCHelpKeyParam* VP_CHelpKeyParam = new ZCHelpKeyParam
(
ZCCheckRef1::PassData(AR_HelpKey1),
ZCCheckRef2::PassData(AR_HelpKey2),
*GetCDerivePtr()
);
/////////////////////////////////////////////////////
return this->TThread::Make
(
&ZtCThreadEx::template
ThreadFuncHelpKey2<TypeData1, TypeData2>,
VP_CHelpKeyParam
);
/*:::::::::::::::::::::::::::::::::::::::::::::::::*/
}/*
template<typename THelpKey1, typename THelpKey2>
bool Make(THelpKey1 AR_HelpKey1, THelpKey2 AR_HelpKey2) */
template
<typename THelpKey1 , typename THelpKey2 , typename THelpKey3 >
bool Make
(THelpKey1 AR_HelpKey1, THelpKey2 AR_HelpKey2, THelpKey3 AR_HelpKey3)
{
typedef ZNsMain::ZtCCheckRef<THelpKey1> ZCCheckRef1;
typedef ZNsMain::ZtCCheckRef<THelpKey2> ZCCheckRef2;
typedef ZNsMain::ZtCCheckRef<THelpKey3> ZCCheckRef3;
typedef typename ZCCheckRef1::TypeData TypeData1 ;
typedef typename ZCCheckRef2::TypeData TypeData2 ;
typedef typename ZCCheckRef3::TypeData TypeData3 ;
typedef ZtCHelpKeyParam3
<TypeData1, TypeData2, TypeData3> ZCHelpKeyParam ;
ZCHelpKeyParam* VP_CHelpKeyParam = new ZCHelpKeyParam
(
ZCCheckRef1::PassData(AR_HelpKey1),
ZCCheckRef2::PassData(AR_HelpKey2),
ZCCheckRef3::PassData(AR_HelpKey3),
*GetCDerivePtr()
);
/////////////////////////////////////////////////////
return this->TThread::Make /*::::::::::::::::::::::*/
(
&ZtCThreadEx::template
ThreadFuncHelpKey3<TypeData1, TypeData2, TypeData3> ,
VP_CHelpKeyParam
);
/*:::::::::::::::::::::::::::::::::::::::::::::::::*/
}/*
template
<typename THelpKey1 , typename THelpKey2 , typename THelpKey3 >
bool Make
(THelpKey1 AR_HelpKey1, THelpKey2 AR_HelpKey2, THelpKey3 AR_HelpKey3)
*/
public:
};/*
template< typename TDerive, typename TThread=ZtCThread<>
>
class ZtCThreadEx //////////////////////////////////////*/
/*//////////////////////////////////////////////////////////////////
object object
.
//////////////////////////////////////////////////////////////////*/
template< typename TSyncData ,
typename TDataArg =const TSyncData& ,
typename TSyncEasy=ZNsMain::ZCCriticSectEasy
>
class ZtCSyncData : public TSyncEasy /*###############*/
{
public :
typedef TSyncData TypeData;
typedef TDataArg TypeArg ;
typedef TSyncEasy TypeSync;
public :
typedef ZNsMain::ZtCAutoKey<TSyncEasy> CAutoKey;
protected:
TSyncData mo_CSyncData;
public :
ZtCSyncData(){}
ZtCSyncData(TDataArg AR_CDataArg)
{
mo_CSyncData=AR_CDataArg;
}/*
ZtCSyncData(TDataArg AR_CDataArg)*/
ZtCSyncData(const ZtCSyncData& rhs)
{
mo_CSyncData=rhs.mo_CSyncData;
}/*
ZtCSyncData(const ZtCSyncData& rhs)*/
ZtCSyncData& operator=(const ZtCSyncData& rhs)
{
mo_CSyncData=rhs.mo_CSyncData; return *this;
}/*
ZtCSyncData& operator=(const ZtCSyncData& rhs)*/
ZtCSyncData& operator=(TDataArg AR_CDataArg)
{
mo_CSyncData=AR_CDataArg; return *this;
}/*
ZtCSyncData& operator=(TDataArg AR_CDataArg)*/
TSyncData& GetData()
{
return mo_CSyncData;
}/*
TSyncData& GetData()*/
const TSyncData& GetData() const
{
return mo_CSyncData;
}/*
const TSyncData& GetData() const*/
operator TSyncData& ()
{
return mo_CSyncData;
}/*
operator TSyncData& ()*/
operator const TSyncData& () const
{
return mo_CSyncData;
}/*
operator const TSyncData& () const*/
public:
};/*
template< typename TSyncData ,
typename TDataArg =const TSyncData& ,
typename TSyncEasy=ZNsMain::ZCCriticSectEasy
>
class ZtCSyncData ////////////////////////////////////*/
/*/////////////////////////////////////////////////////////
object
릿.
/////////////////////////////////////////////////////////*/
template< typename TSyncData ,
typename TDataArg =const TSyncData& ,
typename TSyncEasy=ZNsMain::ZCCriticSectEasy
>
class ZtCSyncObj : public TSyncEasy, public TSyncData
{
public:
typedef TSyncData TypeData;
typedef TDataArg TypeArg ;
typedef TSyncEasy TypeSync;
public:
typedef ZNsMain::ZtCAutoKey<TSyncEasy> CAutoKey;
public:
#define __STATIC_BASE__(R) static_cast<TSyncData&>(R)
ZtCSyncObj(){}
ZtCSyncObj(TDataArg AR_CDataArg)
{
__CAST_BASE__(*this)= AR_CDataArg;
}/*
ZtCSyncObj(TDataArg AR_CDataArg)*/
ZtCSyncObj(const ZtCSyncObj& rhs)
{
__CAST_BASE__(*this)= __CAST_BASE__(rhs);
}/*
ZtCSyncObj(const ZtCSyncObj& rhs)*/
ZtCSyncObj& operator=(const ZtCSyncObj& rhs)
{
__CAST_BASE__(*this)= __CAST_BASE__(rhs); return *this;
}/*
ZtCSyncObj& operator=(const ZtCSyncObj& rhs)*/
ZtCSyncObj& operator=(TDataArg AR_CDataArg)
{
__CAST_BASE__(*this)= AR_CDataArg; return *this;
}/*
ZtCSyncObj& operator=(TDataArg AR_CDataArg)*/
#undef __CAST_BASE__
public:
};/*
template< typename TSyncData ,
typename TDataArg =const TSyncData& ,
typename TSyncEasy=ZNsMain::ZCCriticSectEasy
>
class ZtCSyncObj /////////////////////////////////////*/
#if(_CODE_OLD_)
/*/////////////////////////////////////////////////////////////////////////////
TMutexCondData 2 bool .
TMutexCondData mutex .
ZtCMutexCondDataVar 2 .
ZtCMutexCondDataVar ,
, , ZtCMutexCondDataVar
. .
1 : , .
2 : , .
-- 2025-10-04 18:18
/////////////////////////////////////////////////////////////////////////////*/
template< typename TMutexCondData=ZNsMain::ZtCMutexCondData<>
>
class ZtCMutexCondDataVar : public TMutexCondData /////////////
{
public :
typedef TMutexCondData TypeData ;
typedef TMutexCondData CMutexCondData;
protected:
bool mb_MustWait;
bool mb_WaitCond;
public :
ZtCMutexCondDataVar()
{
mb_MustWait= false;
mb_WaitCond= false;
}/*
ZtCMutexCondDataVar()*/
ZtCMutexCondDataVar(const ZtCMutexCondDataVar& rhs)
{
mb_MustWait= false;
mb_WaitCond= false;
}/*
ZtCMutexCondDataVar(const ZtCMutexCondDataVar& rhs)*/
ZtCMutexCondDataVar& operator=(const ZtCMutexCondDataVar& rhs)
{
return *this; // nothing to do.
}/*
ZtCMutexCondDataVar& operator=(const ZtCMutexCondDataVar& rhs)*/
_SY_ void WaitCondIfMust()
{
/* 이 TMutexCondData 에 접근하는 쓰레드(즉 '잠자는 쓰레드')는
this->mb_MustWait==true
, , WaitCond()
. -- 2025-10-04 18:21
*/
this->TMutexCondData::Lock();
{
if(this->mb_MustWait==true)
{
this->mb_WaitCond=true ;
this->TMutexCondData::WaitCond();
this->mb_WaitCond=false;
}/*
if(this->mb_MustWait==true)*/
}
this->TMutexCondData::UnLock();
}/*
_SY_ void WaitCondIfMust()*/
_SY_ void WakeCondOnBool(bool AB_MustWait)
{
/*////////////////////////////////////////////////////////////////
' ' .
-- 2025-10-04 18:23
SetMustWaitBool() .
AB_MustWait mb_MustWait , WakeCond() ,
this->mb_MustWait==true && AB_MustWait==false,
this->mb_MustWait==true this->mb_MustWait==false
, . -- 2025-10-04 17:23
this->mb_MustWait==true ' '
this->mb_MustWait==false ' '.
,
this->mb_MustWait==true ' '
this->mb_MustWait==false ' '.
-- 2025-10-06 18:29
////////////////////////////////////////////////////////////////*/
this->TMutexCondData::Lock();
{
if(AB_MustWait==this->mb_MustWait)
{
// nothing to do
}
else if(this->mb_MustWait=AB_MustWait)
{
/* nothing to do
this->mb_MustWait==false && AB_MustWait==true,
this->mb_MustWait==false this->mb_MustWait==true
. nothing to do.
*/
}
else if(this->mb_WaitCond==true)
{
/*
this->mb_MustWait==true && AB_MustWait==false,
this->mb_MustWait==true this->mb_MustWait==false
. .
*/
this->TMutexCondData::WakeCond();
this->mb_WaitCond=false;
}/*
else if(this->mb_WaitCond==true)*/
}
this->TMutexCondData::UnLock();
// WakeCondOnBool(true ) : '잠자는 쓰레드'에서 호출.
// WakeCondOnBool(false) : '깨우는 쓰레드'에서 호출.
}/*
_SY_ void WakeCondOnBool(bool AB_MustWait)*/
_SY_ void SetMustWaitTrue (){WakeCondOnBool(true );} // '잠자는 쓰레드'에서 호출.
_SY_ void SetMustWaitFalse(){WakeCondOnBool(false);} // '깨우는 쓰레드'에서 호출.
_SY_ void WakeCondOnTrue (){WakeCondOnBool(true );} // '잠자는 쓰레드'에서 호출.
_SY_ void WakeCondOnFalse (){WakeCondOnBool(false);} // '깨우는 쓰레드'에서 호출.
bool MustWait () const{return mb_MustWait;}
bool DoWaitCond() const{return mb_WaitCond;}
public:
};/*
template< typename TMutexCondData=ZNsMain::ZtCMutexCondData<>
>
class ZtCMutexCondDataVar ///////////////////////////////////*/
#endif //_CODE_OLD_
/*/////////////////////////////////////////////////////////////////////////////
TMutexCondData 1 bool .
TMutexCondData mutex .
ZtCMutexCondVar 2 .
ZtCMutexCondVar ,
, , ZtCMutexCondDataVar
. .
1 : , .
2 : , .
-- 2025-10-04 19:07
,
1 ' ', 2 ' '
.
WaitCondBoolSync() ' '
WakeCondBoolSync() ' ' .
-- 2025-10-06 18:38
/////////////////////////////////////////////////////////////////////////////*/
template< typename TMutexCondData=ZNsMain::ZtCMutexCondData<>
>
class ZtCMutexCondVar : public TMutexCondData /////////////////
{
public :
typedef TMutexCondData TypeData ;
typedef TMutexCondData CMutexCondData;
protected:
bool mb_WaitCond; // 지금 쓰레드가 작업이 없어서 잠잔다.
bool mb_WakeCond; // 어떤 쓰레드가 작업이 있어서 깨웠다.
public :
ZtCMutexCondVar()
{
mb_WaitCond= false;
mb_WakeCond= false;
}/*
ZtCMutexCondVar()*/
ZtCMutexCondVar(const ZtCMutexCondVar& rhs)
{
mb_WaitCond= false;
mb_WakeCond= false;
}/*
ZtCMutexCondVar(const ZtCMutexCondVar& rhs)*/
ZtCMutexCondVar& operator=(const ZtCMutexCondVar& rhs)
{
return *this; // nothing to do.
}/*
ZtCMutexCondVar& operator=(const ZtCMutexCondVar& rhs)*/
_SY_ bool WaitCondBoolSync()
{
/* 이 TMutexCondData 에 접근해 작업을 처리한 쓰레드
,
WaitCond() .
, 2
. 1 .
-- 2025-10-04 18:21
*/
bool VB_Return = false;
this->TMutexCondData::Lock();
{
if(!this->mb_WakeCond && !this->mb_WaitCond)
{
this->mb_WaitCond = true ;
this->TMutexCondData::WaitCond();
this->mb_WaitCond = false;
this->mb_WakeCond = false;
VB_Return = true;
}/*
if(!this->mb_WakeCond && !this->mb_WaitCond)*/
else // '작업'이 발생해 잠들지 않고 계속 작업하는 경우.
{
this->mb_WaitCond = false;
this->mb_WakeCond = false;
}/*
else // '작업'이 발생해 잠들지 않고 계속 작업하는 경우.*/
}
this->TMutexCondData::UnLock();
return VB_Return;
}/*
_SY_ bool WaitCondBoolSync()*/
_SY_ void WakeCondBoolSync()
{
/* 작업이 발생해, 이 TMutexCondData 에 접근해 해당
,
. -- 2025-10-04 19:01
*/
this->TMutexCondData::Lock();
{
if(!this->mb_WakeCond)
{
this->TMutexCondData::WakeCond(); this->mb_WakeCond=true;
}/*
if(!this->mb_WakeCond)*/
}
this->TMutexCondData::UnLock();
}/*
_SY_ void WakeCondBoolSync()*/
bool DoWaitCond() const{return mb_WaitCond;}
public:
};/*
template< typename TMutexCondData=ZNsMain::ZtCMutexCondData<>
>
class ZtCMutexCondVar ///////////////////////////////////////*/
}/*
namespace ZNsMain */
/*////////////////////////////////////////////////////////////////////////////////////
DCLP (Double-Checked Locking Pattern)
http://blog.naver.com/jjoommnn?Redirect=Log&logNo=130036635345
.
MyClass* GP_MyClassSingle=0;
MyClass& GetMyClassSingle()
{
static MyLock SO_MyLock;
if(GP_MyClassSingle!=0) // -- 1)
return *GP_MyClassSingle;
//endif
SO_MyLock.Lock()
{
if(GP_MyClassSingle!=0) // -- 2)
return *GP_MyClassSingle;
//endif
GP_MyClassSingle=new MyClass; // -- 3)
}
SO_MyLock.UnLock()
}
//MyClass& GetMyClassSingle()
GetMyClassSingle() Thread1 Thread2 . Thread1
GetMyClassSingle() 3) .
GP_MyClassSingle NULL MyClass
. .
GP_MyClassSingle volatile . volatile
cache
.
http://msdn.microsoft.com/en-us/library/12a04hfd(VS.80).aspx 를 참고하면 Window
( MSVC++ ) volatile barrier .
http://minjang.egloos.com/2370662 도 좋은 글이다.
Window volatile , Double Checked Lock
.
-- 2009-11-19 14:06:00
## volatile 예제 In http://msdn.microsoft.com/en-us/library/12a04hfd(VS.80).aspx
// spin lock 이 되는 것을 눈여겨 보자.
// volatile.cpp
// compile with: /EHsc /O2
#include <iostream>
#include <windows.h>
using namespace std;
volatile bool Sentinel = true;
int CriticalData = 0;
unsigned ThreadFunc1( void* pArguments ) {
while (Sentinel)
Sleep(0); // volatile spin lock
// CriticalData load guaranteed after every load of Sentinel
cout << "Critical Data = " << CriticalData << endl;
return 0;
}
unsigned ThreadFunc2( void* pArguments ) {
Sleep(2000);
CriticalData++; // guaranteed to occur before write to Sentinel
Sentinel = false; // exit critical section
return 0;
}
int main() {
HANDLE hThread1, hThread2;
DWORD retCode;
hThread1 = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)&ThreadFunc1,
NULL, 0, NULL);
hThread2 = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)&ThreadFunc2,
NULL, 0, NULL);
if (hThread1 == NULL || hThread2 == NULL) {
cout << "CreateThread failed." << endl;
return 1;
}
retCode = WaitForSingleObject(hThread1,3000);
CloseHandle(hThread1);
CloseHandle(hThread2);
if (retCode == WAIT_OBJECT_0 && CriticalData == 1 )
cout << "Success" << endl;
else
cout << "Failure" << endl;
}
## -- volatile 예제
Thread2 GetMyClassSingle() . 1) GP_MyClassSingle
NULL . MyClass return . MyClass
. .
Thread2 MyClass object
.
DCL(Double-Checked Locking) ,
1) object private object
.
2) .
3) ( ) .
4) DCL
.
5) ,
.
singleton double-checked
locking . .
double-checked locking
. static field
.
[] double-checked locking |
http://blog.naver.com/zugm?Redirect=Log&logNo=40003946986
Peter Haggar IBM . Practical Java Programming Language
Guide (Addison-Wesley) .
, , OS .
URL Peter Haggar java out-of-order write , DCL
( re-ordering ), volatile
, volatile java
JVM volatile
.
--
() (CPU)
Window
DWORD SetThreadIdealProcessor(
HANDLE hThread,
DWORD dwIdealProcessor
);
Remarks
You can use the GetSystemInfo function to determine the number of processors on the computer.
You can also use the GetProcessAffinityMask function to check the processors
on which the thread is allowed to run.
Note that GetProcessAffinityMask returns a bit mask
whereas SetThreadIdealProcessor uses an integer value to represent the processor.
To compile an application that uses this function,
define the _WIN32_WINNT macro as 0x0400 or later.
For more information, see Using the SDK Headers.
[] (CPU) api.. ..|
http://blog.naver.com/seoru?Redirect=Log&logNo=40045312217
Linux
int pthread_setaffinity_np(pthread_t th,size_t size,const cpu_set_t *cpuset);
int pthread_getaffinity_np(pthread_t th,size_t size,cpu_set_t *cpuset);
int pthread_attr_setaffinity_np(pthread_attr_t *at,size_t size,const cpu_set_t *cpuset);
int pthread_attr_getaffinity_np(pthread_attr_t *at,size_t size,cpu_set_t *cpuset);
#define _GNU_SOURCE
#include <sched.h>
int sched_setaffinity(pid_t pid, size_t cpusetsize, cpu_set_t *mask);
int sched_getaffinity(pid_t pid, size_t cpusetsize, cpu_set_t *mask);
void CPU_CLR (int cpu, cpu_set_t *set);
int CPU_ISSET(int cpu, cpu_set_t *set);
void CPU_SET (int cpu, cpu_set_t *set);
void CPU_ZERO ( cpu_set_t *set);
,
,
, 2 .
. ZtCMutexCondVar , bool . -- 2025-10-04 19:21
,
. ,
, int long primitive
object ,
.
' ' . '
' object , object
object , .
, ' ' Map .
Map ZNsMain::CKeyValueMap_T<> .
,
. object
, .
. volatile
,
. (
.) volatile
.
-- 2009-12-23 00:24:00
' '
. N N ' '
, '' ,
,
. N
( ) . N
,
. ,
.
, , 1
N ' '
.
,
Configuration State Change Pattern
.
-- 2010-08-19 23:59:00
,
object , object
, object
( object ),
, .
( )
( object ,
. ' '
object , ).
( ) , www.hemose.co.kr
Dead Lock .
-- Dead Lock . -- 2013-07-19 13:36:00
object '' . epoll
IOCP , ' ' .
-- 2010-01-05 00:42:00
CSockInfo_BASE::OnInit(~)
,
CSockInfo_BASE::OnRecvAll(~),
CSockInfo_BASE::OnSendAll(~)
CSockInfo_BASE::OnClose(~)
. ~~
3 . !!
-- 2010-01-05 12:52:00
3 () ,
. , CSockInfo_BASE::OnClose(~)
,
.
, www.hemose.co.kr
(Dead Lock) ,
. ,
"장병들이여! 나는 그대들에게 만족하노라."
, .
-- 2010-01-10 16:14:00
,
'' .
'' object '' , ''
, object '' ,
, ''
.
, '' ,
, ''
' ' , ' '
object '' () .
.
IOCP .
-- 2010-01-05 13:10:00
. , ,
.
.
"항상 술어를 테스트하라! 그리고 다시 한 번 테스트하라!"
(Posix , 124P,
R. , ).
"동기화 영역에서 수행되는 함수가
!"
-- 2010-01-05 19:26:00
, .
CSomeWork , sync1 CSomeWork
func_sync_a (CSomeWork&)
func_sync_b1(CSomeWork&)
func_sync_b2(CSomeWork&)
,
func_sync_not_b(CSomeWork&)
. , CSomeWork my_CSomeWork
func_sync_b1(my_CSomeWork) func_sync_not_b()
func_sync_b2() . .
func_sync_b1 (my_CSomeWork) -- 1
func_sync_not_b(my_CSomeWork) -- 2
func_sync_b2 (my_CSomeWork) -- 3
func_sync_a(my_CSomeWork) . '1'
'3' . , func_sync_b1()
'3' sync1 .
( , func_sync_not_b(my_CSomeWork) func_sync_a(my_CSomeWork)
, Dead Lock .)
sync2 . func_
sync_not_b() ,
.
.
. CSomeWork func_sync_b1()
, func_sync_b2()
mi_func_state , func_sync_b1() , mi_func_state
func_sync_b1() , , my_CSomeWork
func_sync_not_b(my_CSomeWork) func_sync_b2()
. , ,
my_CSomeWork func_sync_b1(my_CSomeWork) , my_CSomeWork.
mi_func_state , func_sync_b1() , func_sync_not_b(my_CSomeWork)
, func_sync_b1(my_CSomeWork)
, CSomeWork .
IOCP CIOCP.H CIOCPEPoll1.H,
CSockInfo_BASE_Win.H CSockInfo_BASE_Linux.H
CSockInfo_BASE_T<>::OnInit()
CSockInfo_BASE_T<>::OnRecvAll()
CSockInfo_BASE_T<>::OnSendAll()
CSockInfo_BASE_T<>::OnClose()
.
Sequential Sync Pattern
.
-- 2010-08-19 23:59:00
(www.hemose.co.kr)
, CSockInfo::OnClose(~) ,
, , CNetBuffSend_T
<>::Fini() ,
for(int i=0;mo_CNetBuffSendList.size();++i)
{
// some code
}
.
for(int i=0;i<mo_CNetBuffSendList.size();++i)
{
// some code
}
. ?
, .
, 1460
, for
3 .
, , ''
. '' '' ''
. '' '' ''
믿 , .
, .
, .
-- 2010-01-23 16:46:00
' '? . . -- 2013-07-19 13:45:00
thread
cat /proc/sys/kernel/threads-max
. -- 2014-08-23 17:38:00
lock 2 .
1. Advisory Lock
* .
* Lock .
* A Lock B Lock
.
2. Mandatory Lock
* Lock .
* Lock Lock
.
* -o mand .
* Mandatory Lock .
* Lock Dead Lock .
////////////////////////////////////////////////////////////////////////////////////*/
#endif //__ZCPPMAIN__PROCESS_H__