ULRE/inc/hgl/thread/DataPost.h

157 lines
2.9 KiB
C++

#ifndef HGL_THREAD_DATA_POST_INCLUDE
#define HGL_THREAD_DATA_POST_INCLUDE
#include<hgl/thread/ThreadMutex.h>
#include<hgl/thread/Semaphore.h>
#include<hgl/type/Stack.h>
namespace hgl
{
/**
* 多线程数据投递模板<br>
* 需要注意每个任务都会重新由空闲线程来进行获取,所以请将连续的任务合并为一个任务,而不是一次大量投递。
*/
template<typename T> class DataPost
{
protected:
List<T *> data_list[2];
int post_index,recv_index;
int recv_offset;
ThreadMutex post_lock,recv_lock;
protected:
void _Swap()
{
if(recv_index){recv_index=0;post_index=1;}
else{recv_index=1;post_index=0;}
recv_offset=0;
}
public:
DataPost()
{
post_index=0;
recv_index=1;
recv_offset=0;
}
virtual ~DataPost()=default;
/**
* 投递一个数据
*/
void Post(T *obj)
{
if(!obj)return;
post_lock.Lock();
data_list[post_index].Add(obj);
post_lock.Unlock();
}
/**
* 投递一批数据
*/
void Post(T **obj,int count)
{
if(!obj)return;
post_lock.Lock();
data_list[post_index].Add(obj,count);
post_lock.Unlock();
}
public:
/**
* 获取一个数据
*/
T *Receive()
{
T *obj=nullptr;
recv_lock.Lock();
int count=data_list[recv_index].GetCount();
if(recv_offset<count)
{
obj=*(data_list[recv_index].GetData()+recv_offset);
++recv_offset;
}
else
{
data_list[recv_index].ClearData(); //清空接收区的数据
post_lock.Lock();
_Swap();
post_lock.Unlock();
count=data_list[recv_index].GetCount();
if(count>0) //如果换出来的区有数据
{
obj=*(data_list[recv_index].GetData()+recv_offset);
++recv_offset;
}
}
recv_lock.Unlock();
return obj;
}
};//template<typename T> class DataPost
/**
* 信号自动交换数据访问模板
*/
template<typename T> class SemDataPost:public DataPost<T>
{
Semaphore sem;
public:
using DataPost<T>::DataPost;
~SemDataPost()=default;
/**
* 释放接收信号
* @param count 信号个数
*/
void PostSem(int count=1)
{
sem.Post(count);
}
/**
* 等待获取一个信号并获取数据
* @param time_out 等待时长
*/
T *WaitSemReceive(const double time_out=5)
{
if(!sem.Acquire(time_out))
return(nullptr);
return this->Receive();
}
/**
* 尝试获取一个信号并获取数据
*/
T *TrySemReceive()
{
if(!sem.TryAcquire())
return(nullptr);
return this->Receive();
}
};//template<typename T> class SemDataPost:public DataPost<T>
}//namespace hgl
#endif//HGL_THREAD_DATA_POST_INCLUDE