CMCore/inc/hgl/thread/Thread.h

229 lines
6.1 KiB
C
Raw Normal View History

2019-08-19 19:19:58 +08:00
#ifndef HGL_THREAD_INCLUDE
#define HGL_THREAD_INCLUDE
#include<hgl/type/DataType.h>
2022-02-08 11:10:20 +08:00
#include<hgl/type/SortedSets.h>
2020-09-03 15:52:46 +08:00
#include<hgl/type/String.h>
2019-08-19 19:19:58 +08:00
#include<hgl/thread/ThreadMutex.h>
2019-08-27 20:26:44 +08:00
#include<hgl/log/LogInfo.h>
2019-08-19 19:19:58 +08:00
namespace hgl
{
void WaitThreadExit(thread_ptr tp,const double &time_out);
/**
* 线.线<br>
* Sleep和Exit函数是给线程内的程序使用的Start,Close,Pause,Rewind是给线程外的程序使用的<br>
* 使Execute函数内即可<br>
* <br>
* if(ProcStartThread()) <br>
* while(Execute()); <br>
* else <br>
* return(0);
* <br>
* ProcEndThread();
*/
class Thread ///线程类
{
friend void WaitThread(Thread **,int,double);
private:
thread_ptr tp=0;
ThreadMutex live_lock;
ThreadMutex exit_lock;
friend THREAD_FUNC ThreadFunc(Thread *tc);
#ifdef _DEBUG
UTF8String thread_addr_string; ///<线程地址用字符串,调试使用
#endif//_DEBUG
public:
virtual ~Thread()=default;
#ifdef _DEBUG
const UTF8String &GetThreadAddressString()const{return thread_addr_string;} ///<取得线程地址字符串
#endif//_DEBUG
/**
* 线
* @return true
* @return false 退
*/
virtual bool Execute()=0; ///<线程的运行函数
virtual bool ProcStartThread() ///<线程启动运行函数,在Execute前被调用
{
#ifdef _DEBUG
2020-07-07 19:14:42 +08:00
u8char thread_addr[(sizeof(thread_ptr)<<1)+1];
2019-08-19 19:19:58 +08:00
DataToUpperHexStr(thread_addr,(uint8 *)&tp,sizeof(thread_ptr));
thread_addr_string=thread_addr;
#endif//_DEBUG
return(true);
}
2022-07-07 21:32:35 +08:00
virtual void ProcEndThread(){} ///<结程结束运行函数,在Execute后被调用
2019-08-19 19:19:58 +08:00
2022-07-07 21:32:35 +08:00
virtual bool DeletedAfterExit()const{return true;} ///<返回在退出线程时,是否删除本对象(注:此函数不可动态变动值)
2019-08-19 19:19:58 +08:00
bool IsLive() ///<当前线程是否还活着
{
if(live_lock.TryLock())
{
//成功了,证明这个线程已经关闭了
live_lock.Unlock();
return(false);
}
return(true);
}
public: //线程运行控制
virtual bool Start(); ///<开始运行当前线程
virtual bool IsCurThread(); ///<是否是当前线程
virtual void Exit() ///<退出当前线程(其它线程调用)
{
exit_lock.Unlock();
}
/**
* (线)退线退<br>
* @param time_out 0线0
*/
virtual void WaitExit(const double &time_out=0)
{
if(!tp)
return;
thread_ptr self_tp=tp;
Exit();
WaitThreadExit(self_tp,time_out);
}
};//class Thread
void WaitThread(Thread **,int,double time=0); ///<等待多个线程中的一个完成
/**
* 线
*/
template<typename THREAD> class MultiThreadManage
{
protected:
2022-02-08 11:10:20 +08:00
SortedSets<THREAD *> thread_set;
2019-08-19 19:19:58 +08:00
public:
virtual ~MultiThreadManage()
{
Close();
}
THREAD *GetThread(int index)
{
THREAD *result;
if(thread_set.Get(index,result))
return result;
return nullptr;
}
/**
* 线
* @return
*/
bool Add(THREAD *p)
{
if(!p)return(false);
return(thread_set.Add(p)!=-1);
}
/**
* 线
*/
void Delete(THREAD *p)
{
if(!p)return;
thread_set.Delete(p);
}
/**
* 线
*/
void Close()
{
const int count=thread_set.GetCount();
THREAD **p=thread_set.GetData();
for(int i=0;i<count;i++)
{
(*p)->WaitExit();
++p;
}
thread_set.Clear();
2019-08-19 19:19:58 +08:00
}
/**
* 线
* @return 线
*/
int Start()
{
const int count=thread_set.GetCount();
THREAD **p=thread_set.GetData();
int total=0;
for(int i=0;i<count;i++)
{
if((*p)->Start())
++total;
++p;
}
return total;
}
/**
* 线
*/
int IsLive()
{
const int count=thread_set.GetCount();
THREAD **p=thread_set.GetData();
int total=0;
for(int i=0;i<count;i++)
{
if((*p)->IsLive())
++total;
++p;
}
return total;
}
};//class MultiThreadManage
}//namespace hgl
#endif//HGL_THREAD_INCLUDE