内存池
其实和qt无关,不过既然已经使用qt,就加上吧,无论使用qt与否,都额可以使用,限制为片元固定大小内存,非固定内存内存池可以看我的其他文章。
数据结构定义#ifndef C_MEM_H
#define C_MEM_H
#include
#include
#include
#include
#include
#include
#include
enum st_status
{
st_read,
st_write
};
struct s_mem
{
uint8_t *v_data = NULL;
int v_len = 0;
std::atomic v_status;// = st_status::st_write;
int v_type ;
int w;
int h;
s_mem()
{
v_status = st_write;
}
~s_mem()
{
if(v_data!=NULL)
delete v_data;
}
void set(uint8_t *data,int len)
{
if(len> v_len)
{
if(v_data !=NULL)
{
delete []v_data;
v_data = NULL;
v_len = 0;
}
}
if(v_data == NULL)
{
v_data = new uint8_t[len];
v_len = len;
}
memcpy(v_data,data, len);
v_status = st_read;//可以读
}
};
回调函数声明
typedef void(*func_callback)(s_mem *mem);
实现
#define NUM_CACHE 10
class c_mem
{
s_mem v_m[NUM_CACHE];
volatile int v_r = 0;
volatile int v_w = 0;
public:
c_mem()
{
}
int push(uint8_t *data,int len)
{
//int time = 0;
if(v_m[v_w].v_status != st_write)
{
//std::this_thread::yield();
//std::this_thread::sleep_for(std::chrono::milliseconds(5));
//try--;
//if(++time == 3)
return -1;
}
v_m[v_w].set(data,len);
int tmp = (v_w +1 )% NUM_CACHE;
v_w = tmp;
return 0;
}
s_mem *pop()
{
//int time = 0;
if(v_m[v_r].v_status !=st_read)
{
//std::this_thread::yield();
//if(++time = 3)
return NULL;
}
//if(cb!=NULL)
//{
s_mem *sm = &v_m[v_r];
int tmp = (v_r +1 )% NUM_CACHE;
v_r = tmp;
return sm;
//sm->v_status = st_write;
//}
return 0;
}
};
template
class RingBuffer
{
public:
RingBuffer(unsigned size): m_size(size), m_front(0), m_rear(0)
{
m_data = new T[size];
}
~RingBuffer()
{
delete [] m_data;
m_data = NULL;
}
inline bool isEmpty() const
{
return m_front == m_rear;
}
inline bool isFull() const
{
return m_front == (m_rear + 1) % m_size;
}
bool push(const T& value)
{
if(isFull())
{
return false;
}
m_data[m_rear] = value;
m_rear = (m_rear + 1) % m_size;
return true;
}
bool push(const T* value)
{
if(isFull())
{
return false;
}
m_data[m_rear] = *value;
m_rear = (m_rear + 1) % m_size;
return true;
}
inline bool pop(T& value)
{
if(isEmpty())
{
return false;
}
value = m_data[m_front];
m_front = (m_front + 1) % m_size;
return true;
}
inline unsigned int front()const
{
return m_front;
}
inline unsigned int rear()const
{
return m_rear;
}
inline unsigned int size()const
{
return m_size;
}
private:
unsigned int m_size;// 队列长度
int m_front;// 队列头部索引
int m_rear;// 队列尾部索引
T* m_data;// 数据缓冲区
};
#endif // C_MEM_H
使用
多线程调用示例,比较简单,可自行查看
#ifndef C_THREAD_H
#define C_THREAD_H
#include
#include
#include
#include
#include
#include
#include "c_mem.h"
#include
#define USE_CMEM_RING 1
class c_thread: public QThread
{
Q_OBJECT
private:
QMutex v_mux_data;
QMutex v_mux;
QWaitCondition v_con;
std::queue v_data;
//QReadWriteLock lock;
c_mem v_data2;
volatile bool v_stop = true;
public:
func_callback v_cb = NULL;
public:
c_thread(QObject* parent = nullptr);
protected:
s_mem *popdata()
{
#if (USE_CMEM_RING)
s_mem *data = NULL;
data = v_data2.pop();
return data;
#else
s_mem *data = NULL;
v_mux_data.lock();
if(!v_data.empty())
{
data = v_data.front();
v_data.pop();
}
v_mux_data.unlock();
return data;
#endif
}
void clear()
{
#if (!USE_CMEM_RING)
v_mux_data.lock();
while(!v_data.empty())
{
s_mem *data = v_data.front();
v_data.pop();
delete data;
}
v_mux_data.unlock();
#endif
}
public:
//通知有数据
void notify()
{
v_mux.lock();
v_con.notify_one();
v_mux.unlock();
}
void stop()
{
v_stop = true;
//通知锁定解除
notify();
quit();
wait();
}
void pushdata(uint8_t *data, int len)
{
#if (USE_CMEM_RING)
int ret = -1;
while(ret !=0)
{
ret = v_data2.push(data,len);
if(ret!=0)
{
if(v_stop == 1)
return ;
//QThread::msleep(2);
QThread::yieldCurrentThread();
}
}
notify();
#else
s_mem *mydata = new s_mem;
mydata->set(data,len);
v_mux_data.lock();
v_data.push(mydata);
v_mux_data.unlock();
notify();
#endif
}
void setcb(func_callback cb)
{
v_cb = cb;
}
signals:
void threadSignal(int);
public slots:
void threadSlot(const int);
protected:
void run() override;
};
// controller用于启动线程和处理线程执行结果
class Controller : public QObject
{
Q_OBJECT
c_thread* v_thd;
protected:
public:
Controller(QObject *parent) : QObject(parent)
{
}
~Controller()
{
}
void stop()
{
v_thd->stop();
}
void start(func_callback cb)
{
v_thd = new c_thread;
v_thd->setcb(cb);
connect(v_thd,SIGNAL(threadSignal(int)),this, SLOT(handleResults(int)));
connect(this,SIGNAL(operate(const int)),v_thd, SLOT(threadSlot(const int)));
// 该线程结束时销毁
connect(v_thd, SIGNAL(&QThread::finished), this, SLOT(&QObject::deleteLater));
// 启动该线程
v_thd->start();
QThread::msleep(5);
emit operate(999);
}
void add_data(uint8_t *data,int len)
{
v_thd->pushdata(data,len);
}
public slots:
// 处理线程执行的结果
void handleResults(int rslt)
{
std::cout
关注
打赏
最近更新
- 深拷贝和浅拷贝的区别(重点)
- 【Vue】走进Vue框架世界
- 【云服务器】项目部署—搭建网站—vue电商后台管理系统
- 【React介绍】 一文带你深入React
- 【React】React组件实例的三大属性之state,props,refs(你学废了吗)
- 【脚手架VueCLI】从零开始,创建一个VUE项目
- 【React】深入理解React组件生命周期----图文详解(含代码)
- 【React】DOM的Diffing算法是什么?以及DOM中key的作用----经典面试题
- 【React】1_使用React脚手架创建项目步骤--------详解(含项目结构说明)
- 【React】2_如何使用react脚手架写一个简单的页面?