CMCore/inc/hgl/thread/Thread.h

231 lines
6.2 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#ifndef HGL_THREAD_INCLUDE
#define HGL_THREAD_INCLUDE
#include<hgl/type/DataType.h>
#include<hgl/type/Set.h>
#include<hgl/type/BaseString.h>
#include<hgl/thread/ThreadMutex.h>
#include<hgl/log/LogInfo.h>
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
char thread_addr[(sizeof(thread_ptr)<<1)+1];
DataToUpperHexStr(thread_addr,(uint8 *)&tp,sizeof(thread_ptr));
thread_addr_string=thread_addr;
#endif//_DEBUG
return(true);
}
virtual void ProcEndThread(){} ///<结程结束运行函数,在Execute后被调用
virtual bool IsExitDelete()const{return true;} ///<返回在退出线程时,是否删除本对象(注:此函数不可动态变动值)
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); ///<等待多个线程中的一个完成
bool CreateThread(Thread *); ///<创建一个线程
/**
* 简单的多线程管理
*/
template<typename THREAD> class MultiThreadManage
{
protected:
Set<THREAD *> thread_set;
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.ClearData();
}
/**
* 启动所有线程
* @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