first commit
This commit is contained in:
230
inc/hgl/thread/Thread.h
Normal file
230
inc/hgl/thread/Thread.h
Normal file
@@ -0,0 +1,230 @@
|
||||
#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/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
|
Reference in New Issue
Block a user