最近在做一个手机上多帧配准后叠加平均计算中,需要保证实时性,此时要将输入数据、处理数据、获取结果等过程用各自的线程处理,同时增加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; }