From 8b6ea4118fe38aaf9a2db632deb9c6a2b6fd785a Mon Sep 17 00:00:00 2001 From: sauron Date: Sat, 4 Oct 2025 20:40:17 +0900 Subject: [PATCH] commit 2025-10-04 20:40 replace ZtCMutexCondDataVar with ZtCMutexCondVar : ZCppMain/ZCProcess.H --- ZCppMain/ZCProcess.H | 225 ++++++++++++++++++++++++++++++++++++++++++++++----- ZCppMain/ZMainHead.H | 12 --- 2 files changed, 203 insertions(+), 34 deletions(-) diff --git a/ZCppMain/ZCProcess.H b/ZCppMain/ZCProcess.H index 4cb1956..b48b732 100644 --- a/ZCppMain/ZCProcess.H +++ b/ZCppMain/ZCProcess.H @@ -1004,12 +1004,26 @@ namespace ZNsMain 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<> @@ -1031,29 +1045,64 @@ namespace ZNsMain }/* ZtCMutexCondDataVar()*/ - void CheckWaitCond() + ZtCMutexCondDataVar(const ZtCMutexCondDataVar& rhs) { - if(this->mb_MustWait==true) - { - 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(); - }/* - if(this->mb_MustWait==true)*/ + mb_MustWait= false; + mb_WaitCond= false; }/* - void CheckWaitCond()*/ + ZtCMutexCondDataVar(const ZtCMutexCondDataVar& rhs)*/ - - void SetMustWaitBool(bool AB_MustWait) + 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->TMutexCondData::Lock(); { if(AB_MustWait==this->mb_MustWait) @@ -1062,20 +1111,41 @@ namespace ZNsMain } else if(this->mb_MustWait=AB_MustWait) { - // nothing to do + /* 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) : '깨우는 쓰레드'에서 호출. }/* - void SetMustWaitBool(bool AB_MustWait)*/ + _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;} @@ -1087,6 +1157,115 @@ namespace ZNsMain > class ZtCMutexCondDataVar ///////////////////////////////////*/ +#endif //_CODE_OLD_ + + + + /*///////////////////////////////////////////////////////////////////////////// + + ■ TMutexCondData 클래스를 상속하여 대기 상태를 표시하는 1 개의 bool 멤버를 갖는다. + + ■ TMutexCondData 클래스 타입은 mutex 와 조건변수를 가지고 있어야 한다. + + ■ ZtCMutexCondVar 에 접근하는 쓰레드는 크게 2개가 있다. + + 하나는 ZtCMutexCondVar 를 가지고 있는 쓰레드로, 주로 작업이 없으면 잠드는 + 쓰레드이고, 또 하나는 해야 할 작업이 발생했는데, ZtCMutexCondDataVar 에서 + 잠들어 있는 쓰레드를 깨우는 쓰레드이다. 즉 아래로 정리하자. + + 1번 쓰레드 : 잠자는 쓰레드, 작업이 없으면 잠자는 쓰레드. + 2번 쓰레드 : 깨우는 쓰레드, 작업이 있으면 깨우는 쓰레드. + + -- 2025-10-04 19:07 + + /////////////////////////////////////////////////////////////////////////////*/ + + template< typename TMutexCondData=ZNsMain::ZtCMutexCondData<> + > + class ZtCMutexCondVar : public TMutexCondData ///////////////// + { + public : + typedef TMutexCondData TypeData ; + typedef TMutexCondData CMutexCondData; + protected: + bool mb_WaitCond; + public : + + ZtCMutexCondDataVar() + { + mb_WaitCond= false; + }/* + ZtCMutexCondDataVar()*/ + + ZtCMutexCondDataVar(const ZtCMutexCondDataVar& rhs) + { + mb_WaitCond= false; + }/* + ZtCMutexCondDataVar(const ZtCMutexCondDataVar& rhs)*/ + + ZtCMutexCondDataVar& operator=(const ZtCMutexCondDataVar& rhs) + { + return *this; // nothing to do. + }/* + ZtCMutexCondDataVar& operator=(const ZtCMutexCondDataVar& rhs)*/ + + + _SY_ bool WaitCondOnExec() + { + /* 이 TMutexCondData 에 접근해 작업을 처리한 쓰레드 + (즉 '잠자는 쓰레드')는 작업이 끝나면 WaitCond() + 에서 대기한다. + + 다만, 이 함수로 2개 이상의 쓰레드가 대기하는 것은 + 잘못된 설계이다. 어디까지나 1개 쓰레드 대기 용이다. + + -- 2025-10-04 18:21 + */ + bool VB_Return = false; + + this->TMutexCondData::Lock(); + { + if(!this->mb_WaitCond) + { + this->mb_WaitCond = true ; + this->TMutexCondData::WaitCond(); + this->mb_WaitCond = false; + + VB_Return = true; + }/* + if(!this->mb_WaitCond)*/ + } + this->TMutexCondData::UnLock(); + + return VB_Return; + }/* + _SY_ bool WaitCondOnExec()*/ + + + _SY_ void WakeCondOnExec() + { + /* 작업이 발생해, 이 TMutexCondData 에 접근해 해당 + 쓰레드를 깨워 작업을 시키려는 쓰레드(깨우는 쓰레드) + 가 호출한다. -- 2025-10-04 19:01 + */ + this->TMutexCondData::Lock(); + { + if(this->mb_WaitCond==true) this->TMutexCondData::WakeCond(); + } + this->TMutexCondData::UnLock(); + }/* + _SY_ void WakeCondOnExec()*/ + + + bool DoWaitCond() const{return mb_WaitCond;} + + public: + };/* + template< typename TMutexCondData=ZNsMain::ZtCMutexCondData<> + > + class ZtCMutexCondVar ///////////////////////////////////////*/ + + }/* namespace ZNsMain */ @@ -1291,6 +1470,8 @@ namespace ZNsMain */ 고 있는지 동작중인지를 판단하는 변수와, 쓰레드를 재워야하는지 아닌지를 표시하는 변 수, 이렇게 2 개가 필요하다. + 그렇지 않다. ZtCMutexCondVar 을 보면, bool 멤버 하나로도 괜찮다. -- 2025-10-04 19:21 + ■ 긴 작업을 하고 있는 쓰레드의 경우, 그 쓰레드가 현재 어디까지 작업을 하고 있는지 알 고 싶을 때가 있다. 이때 작업 진행 정보를 멤버 변수에 담아 두게 되는데, 다른 쓰레드 에서 이 진행 정보 멤버에 접근할 때, 해당 멤버 변수가 int 나 long 과 같은 primitive diff --git a/ZCppMain/ZMainHead.H b/ZCppMain/ZMainHead.H index 0c35ca5..0ea1a7f 100644 --- a/ZCppMain/ZMainHead.H +++ b/ZCppMain/ZMainHead.H @@ -3495,17 +3495,10 @@ namespace ZNsMain template class ZtCAllocClass : public ZCAllocator { public: - #if(_CODE_OLD_) - TType* NewMem (size_t AL_AllocSize){return (TType*)::malloc(AL_AllocSize) ;} - TType* NewArrMem(size_t AL_AllocSize){return (TType*)::malloc(AL_AllocSize*sizeof(TType));} - public: - void DeleteMem(void* AP_Void){if(AP_Void!=0) ::free(AP_Void);} - #else TType* InitMem (size_t AL_AllocSize){return (TType*)::malloc(AL_AllocSize) ;} TType* InitArrMem(size_t AL_AllocSize){return (TType*)::malloc(AL_AllocSize*sizeof(TType));} public: void FiniMem (void* AP_Void){if(AP_Void!=0) ::free(AP_Void);} - #endif public: };/* template class ZtCAllocClass : public ZCAllocator*/ @@ -3514,13 +3507,8 @@ namespace ZNsMain class ZCAllocClass : public ZCAllocator { public: - #if(_CODE_OLD_) - void* NewMem (size_t AL_AllocSize){return ::malloc(AL_AllocSize) ;} - void DeleteMem(void* AP_Void ){if(AP_Void!=0) ::free(AP_Void);} - #else void* InitMem (size_t AL_AllocSize){return ::malloc(AL_AllocSize) ;} void FiniMem (void* AP_Void ){if(AP_Void!=0) ::free(AP_Void);} - #endif public: };/* class ZCAllocClass : public ZCAllocator*/