qt memring固定片元内存池制作
Posted qianbo_insist
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了qt memring固定片元内存池制作相关的知识,希望对你有一定的参考价值。
内存池
其实和qt无关,不过既然已经使用qt,就加上吧,无论使用qt与否,都额可以使用,限制为片元固定大小内存,非固定内存内存池可以看我的其他文章。
数据结构定义
#ifndef C_MEM_H
#define C_MEM_H
#include <stdint.h>
#include <memory.h>
#include <vector>
#include <thread>
#include <chrono>
#include <atomic>
#include <assert.h>
enum st_status
st_read,
st_write
;
struct s_mem
uint8_t *v_data = NULL;
int v_len = 0;
std::atomic<st_status> 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 T>
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<QThread>
#include <queue>
#include <QDebug>
#include <QMutex>
#include <QWaitCondition>
#include <QReadWriteLock>
#include "c_mem.h"
#include <iostream>
#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<s_mem*> 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<<"receive the resultReady signal---------------------------------";
std::cout<<"current thread ID:"<<QThread::currentThreadId()<<'\\n';
std::cout<<"the last result is:"<<rslt;
signals:
// 发送信号触发线程
void operate(const int);
;
#endif // C_THREAD_H
#include <QDebug>
#include <iostream>
c_thread::c_thread(QObject *parent)
//void c_thread::notify()
//
//
void c_thread::run()
qDebug()<<"myThread run() start to execute";
v_stop = false;
//读取数据
int count = 0;
while(isRunning())
//得到有数据的信号,没有数据将阻塞,
v_mux.lock();
v_con.wait(&v_mux);
v_mux.unlock();
while(1)
if(v_stop)
qInfo()<<"out of thread in 1"<<endl;
break;
s_mem *data = popdata();
if(data)
if(v_cb!=NULL)
v_cb(data);
#if (!USE_CMEM_RING)
delete data;
#else
//状态可写
data->v_status = st_status::st_write;
#endif
count++;
else
break;
if(v_stop)
break;
std::cout<<"out of thread"<<std::endl;
clear();
// 发送结束信号
emit threadSignal(count);
exec();
std::cout<<"thread run over"<<std::endl;
void c_thread::threadSlot(const int val)
qDebug()<<"myThreadSlot() start to execute";
qDebug()<<"current thread ID:"<<QThread::currentThreadId()<<'\\n';
#include <QCoreApplication>
#include <c_mem.h>
#include "c_thread.h"
#include <string>
#include <iostream>
#include <QDebug>
#include <QLoggingCategory>
static void callback(s_mem *mem)
if(mem!=NULL)
std::string s((char*)mem->v_data,mem->v_len);
std::cout<<s<<std::endl;
int main(int argc, char *argv[])
QCoreApplication a(argc, argv);
QLoggingCategory::defaultCategory()->setEnabled(QtDebugMsg, true);
qDebug()<<"start main"<<endl;
QThread::sleep(2);
Controller ctrl(&a);
ctrl.start(callback);
for(int i = 0;i<10000;i++)
char buffer[128];
sprintf(buffer,"this is data %d",i);
ctrl.add_data((uint8_t*)buffer,strlen(buffer));
QThread::msleep(5);
// std::cout<<"push "<<i<<std::endl;
QThread::sleep(2);
for(int i = 10000;i<20000;i++)
char buffer[128];
sprintf(buffer,"this is data %d",i);
ctrl.add_data((uint8_t*)buffer,strlen(buffer));
QThread::msleep(5);
// std::cout<<"push "<<i<<std::endl;
QThread::sleep(2);
for(int i = 20000;i<30000;i++)
char buffer[128];
sprintf(buffer,"this is data %d",i);
ctrl.add_data((uint8_t*)buffer,strlen(buffer));
QThread::msleep(5);
// std::cout<<"push "<<i<<std::endl;
ctrl.stop();
qInfo()<<"here is over"<<endl;
固定内存块尺寸的内存池原理及代码