带缓冲区的多线程读写数据

//vRecorder.hpp
//vov
#ifndef V_RECORDER_HPP
#define V_RECORDER_HPP

#include <iostream>
#include <string>
#include <thread>
#include <mutex>
#include <condition_variable>
#include <atomic>

#include "Recorder.h"
#include "vBufferChar.hpp"

class vRecorder
{
    void *handler_;
    std::string config_path_;
    int buffer_size_;
public:
    vRecorder(std::string config_path,int size);
    ~vRecorder();
    bool init();
    bool start();
    bool stop();
    void release();
    int read(char* data,int size);
private:
    std::unique_ptr<vBufferChar> uptr_buffer_;
    std::unique_ptr<std::thread> uptr_thread_record_;
    std::mutex mtx_buf_;
    std::condition_variable cv_buf_;
    std::atomic<bool> flag_record_;

    void thread_record();
};

//public
vRecorder::vRecorder(std::string config_path,int size=16000)
    :handler_(nullptr),
    uptr_buffer_(nullptr),
    uptr_thread_record_(nullptr),
    flag_record_(false)
{
    config_path_=config_path;
    uptr_buffer_.reset(new vBufferChar(size));
}

vRecorder::~vRecorder() {
    if(flag_record_&&uptr_thread_record_) {
        flag_record_=false;
        if(uptr_thread_record_->joinable()) {
            uptr_thread_record_->join();
        }
    }

    if(handler_) {
        Recorder_Release(handler_);
    }
    
    std::cout<<"[vRecorder]"<<__FUNCTION__<<std::endl;
}

bool vRecorder::init() {
    handler_=Recorder_Init(config_path_.data());
    return (!handler_)?false:true;
}

bool vRecorder::start() {
    if(handler_&&!uptr_thread_record_&&!flag_record_) {
        uptr_thread_record_.reset(new std::thread(&vRecorder::thread_record,this));
        flag_record_=(!uptr_thread_record_)?false:true;
    }

    if(handler_&&uptr_thread_record_) {
        flag_record_=true;
    }
    
    return flag_record_;
}

bool vRecorder::stop() {
    if(flag_record_) {
        flag_record_=false;
        if(uptr_thread_record_->joinable()) {
            uptr_thread_record_->join();
        }
    }
    return true;
}

void vRecorder::release() {
    flag_record_=false;
    if(uptr_thread_record_->joinable()) {
        uptr_thread_record_->join();
    }

    std::cout<<"[vRecorder]"<<__FUNCTION__<<std::endl;
}

int vRecorder::read(char*data,int size) {
    if(size<=0) {
        return 0;
    }
    
    int read_size=0;
    {
        std::unique_lock<std::mutex> lock(mtx_buf_);
        cv_buf_.wait(lock,[this]{return uptr_buffer_->size()>0;});
        read_size=uptr_buffer_->read(data,size);
    }
    
    return read_size;
}

//private
void vRecorder::thread_record() {
    while(flag_record_) {
        int16_t *data{nullptr};
        int res=Recorder_Read(handler_,&data);
        if(res>0) {
            {
                std::unique_lock<std::mutex> lock(mtx_buf_);
                uptr_buffer_->write((const char*)data,res<<1);
                cv_buf_.notify_all();
            }
        }
    }
}

#endif
原文地址:https://www.cnblogs.com/smallredness/p/10948534.html