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;
    固定内存块尺寸的内存池原理及代码

[分享源码] 高效内存池;动态内存池|单元内存池

内存池技术畅想

kylin源码分析-内存池

开胃菜-定长内存池

开胃菜-定长内存池