算法中的多线程处理方法简单总结

最近在做一个手机上多帧配准后叠加平均计算中,需要保证实时性,此时要将输入数据、处理数据、获取结果等过程用各自的线程处理,同时增加mutex(std中)互斥量保证线程处理中数据的占用安全。

这里就简单写一个C++的程序例子(肯定会有bug,因为使用办公电脑,考虑信息安全不能在VS中调试):

(完全是在博客园的插入代码中的对话框中编写,代码错误会很多,仅用于参考线程及互斥量的使用方法,当然这也是基本的使用,还有很多需要优化和加深的。)

#定义纯虚类,目的便于集成时父类指向子类的转换
class CMFModule {
    public:
        CMFModule() {};
        virtual ~CMFModule() = 0;
        virtual int init(int w, int h) = 0;
        virtual int proc(Mat& src) = 0; 
        virtual int getRes(Mat& dst) = 0;
        virtual setStopStatus(bool status) = 0;  
}
CMFModule::~CMFModule(){}; # 纯虚类中析构函数不写实现会报错!

# 其中一个子类
class CMFSlotModule: public CMFModule {
    public:
        CMFSlotModule() {};
        ~CMFSlotModule() {};
        int init(int w, int h);
        int proc(Mat& src); 
        int getRes(Mat& dst);
        void setStopStatus(bool status);
        bool getStopStatus();
        void setRefreshStatus(bool status);
        bool getRefreshStatus();
    private:
        int procThread();
        int getResultThread();
        int startThread();
        thread mPThread; # 处理线程
        thread mRThread; # 结果线程
    private:
        mutex mSrcMutex;
        mutex mRefMutex;
        mutex mAccMutex;
        mutex mResMutex;
        mutex mStopMutex;
        mutex mRefreshMutex;
        int input(Mat& src);
        int read(Mat& src);
        int align(Mat& src, Mat& dst);
        int accProc(Mat& inData);
        int avgProc(Mat& dst);
        int copyRes(Mat& src);
   private:
        int mW;
        int mH;
        bool mStopStatus; # 监测是否停止处理,判断是否结束进程
        bool mRefreshStatus; # 结果刷新状态
        bool mProcThreadRunStatus = false;
        bool mResThreadRunStatus = false;
        queue<Mat> mSrcQue; # 缓存输入图像数据
        Mat mRef; # 参考图像
        Mat mAcc; # 累加图像
        Mat mDst; # 保存结果
}

# 实现的一部分,只写线程相关的部分
int CMFSlotModule::proc(Mat& src){
    if(# first frame){
        # 处理第一帧、Mat初始化等操作
    }else{
        input(src);
    }
    startThread();
    resturn 0;
}
int CMFSlotModule::getRes(Mat& dst){
    lock_guard<mutex> resMutex(mResMutex);
    dst = mDst;
    if(getStopStatus()){
        # 释放一部分空间
        setStopStatus(false); # 用于结束线程
    }
    return 0;
}
void CMFSlotModule::setStopStatus(bool status){
    
}
bool CMFSlotModule::getStopStatus(){
    
}
# 这里只写一种关于状态的互斥量使用,其它相似
void CMFSlotModule::setRefreshStatus(bool status){
    lock_guard<mutex> refreshMutex(mRefreshMutex);
    mResThreadRunStatus = status; # 每累加完一次就要更新一次状态
}
bool CMFSlotModule::getRefreshStatus(){
    return mResThreadRunStatus;
}

int CMFSlotModule::input(Mat& src){
    # 访问mSrcQue加上互斥锁,这在main线程和子线程间都在调用
    lock_guard<mutex> srcMutex(mSrcMutex);
    if(!mSrcQue.empty()) return 0;
    mSrcQue.push(src);
    return 0;
}

int CMFSlotModule::read(Mat& src){
    # 访问mSrcQue加上互斥锁,这在main线程和子线程间都在调用
    lock_guard<mutex> srcMutex(mSrcMutex);
    if(!mSrcQue.empty()) return 0;
    src = mSrcQue.front();
    mSrcQue.pop();
    return 0;
}

int CMFSlotModule::align(Mat& src, Mat& dst){
    lock_guard<mutex> refMutex(mRefMutex);
    # 配准计算
    return 0;
}

int CMFSlotModule::accProc(Mat& inData){
    lock_guard<mutex> accMutex(mAccMutex);
    accumulate(inData, mAcc);
    return 0;
}

int CMFSlotModule::avgProc(Mat& dst){
    lock_guard<mutex> accMutex(mAccMutex);
    # 求平均处理,需要统计帧数;
    return 0;
}

int CMFSlotModule::copyRes(Mat& src){
    lock_guard<mutex> resMutex(mResMutex);
    mDst = src;
    return 0;
}

int CMFSlotModule::procThread() {
    Mat src, dst;
    while(true){
        if(getStopStatus()) break;
        read(src); # 从mSrcQue中读取数据
        if(src.empty()) continue;
        align(src, dst); # 配准计算
        accProc(dst); # 累加
    }
    retrun 0;
}

int CMFSlotModule::getResultThread() {
    Mat dst;
    while(true){
        if(getStopStatus()) break;
        if(!getRefreshStatus()) continue;
        avgProc(dst); # 求平均
        copyRes(dst); # 存于mDst
        setRefreshStatus(false); # 取完结果将刷新状态设置为false
    }
    retrun 0;
}

int CMFSlotModule::startThread() {
    int res = 0;
    if(mProcThreadRunStatus == false&& mResThreadRunStatus == false)
    {
        mPThread = thread([&] {res = procThread()});
        mPThread.detach(); # 与主线程不同步处理
        mRThread = thread([&] {res = getResultThread()});
        mRThread.detach(); # 与主线程不同步处理
        mProcThreadRunStatus = true;
        mResThreadRunStatus = true;
    }
    retrun res;
}

int main(){
    # 这里为了方便,就不创建父类指针指向子类了
    CMFSlotModule* mfsm = new CMFSlotModule();
    mfsm->init(1024, 1024);
    while(true){
        # 连续地读取某数据src
        Mat src;
        mfsm->proc(src);
        Mat dst;
        mfsm->getRes(dst);
    }
    return 0;
}    

 

上一篇:C语言 strcpy 函数 - C语言零基础入门教程


下一篇:Jquery 复习练习(01)