前言:异步执行经常要用到2个函数,一个函数处理UI线程的调用,另外一个函数处理内核线程调用。并且中间要用很多命令来转接不同的函数。这样函数的代码量和处理要麻烦很多。可以用模板函数做一下转接。
模板函数如下:(用到的函数打包知:std::bind与std::function详解)
#pragma once #include "stdafx.h" #include <stdio.h> #include <iostream> #include <functional> #include <vector> #include <mutex> class CPerformFunction { public: class CQueueCmd { public: CQueueCmd(void* cmd, bool sync) { _data = cmd; m_isSync = sync; _isFinish = false; m_isDel = false; } ~CQueueCmd() {} void wait() { if (!m_isSync) return; std::unique_lock<std::mutex> lock(_mutex); if (!_isFinish) _cond.wait(lock); lock.unlock(); } void notify() { if (!m_isSync) return; std::unique_lock<std::mutex> lock(_mutex); _isFinish = true; _cond.notify_one(); lock.unlock(); } void* getCmd() { return _data; } public: bool m_isSync; bool m_isDel; private: void* _data; std::mutex _mutex; std::condition_variable _cond; bool _isFinish; //命令執行完成 }; public: CPerformFunction() {} virtual ~CPerformFunction() { std::unique_lock<std::mutex> lock(m_mtxCmd); auto iterCmd = m_vecCmd.begin(); for (; iterCmd != m_vecCmd.end(); iterCmd++) { std::function<void()> *f = (std::function<void()>*)(*iterCmd)->getCmd(); if (f) { //释放这里不需要执行函数 delete f; f = NULL; } (*iterCmd)->notify(); if (!(*iterCmd)->m_isSync) { m_vecDelCmd.push_back((*iterCmd)); } } m_vecCmd.clear(); auto iterDelCmd = m_vecDelCmd.begin(); while (iterDelCmd != m_vecDelCmd.end()) { while (!(*iterDelCmd)->m_isDel) { Sleep(1); } delete (*iterDelCmd); m_vecDelCmd.erase(iterDelCmd); } } template<class Object, class T, class... Args> T performStdObjectFuncWithReturn(Object* object, T(__stdcall Object::*method)(Args...), Args... args) { return performClosureWithReturn<T>(std::bind(method, object, args...)); } template<class Object, class T, class... Args> T performObjectFuncWithReturn(Object* object, T (Object::*method)(Args...), Args... args) { return performClosureWithReturn<T>(std::bind(method, object, args...)); } template<class T> T performClosureWithReturn(std::function<T()> closure) { T* return_value = new T; std::function<void()> func = std::bind(&CPerformFunction::wrap<T>, this, closure, return_value); exec(func); T value = *(T*)return_value; delete return_value; return value; } template<class T, class... Args> T performStdFuncWithReturn(T(__stdcall *method)(Args...), Args... args) { return performClosureWithReturn<T>(std::bind(method, args...)); } template<class T, class... Args> T performFuncWithReturn(T(*method)(Args...), Args... args) { return performClosureWithReturn<T>(std::bind(method, args...)); } template<class Object, class... Args> void performStdObjectFuncWithoutReturn(Object* object, void(__stdcall Object::*method)(Args...), Args... args) { std::function<void()> func = std::bind(method, object, args...); exec(func); } template<class Object, class... Args> void performObjectFuncWithoutReturn(Object* object, void(Object::*method)(Args...), Args... args) { std::function<void()> func = std::bind(method, object, args...); exec(func); } template<class... Args> void performStdFuncWithoutReturn(void(__stdcall *method)(Args...), Args... args) { std::function<void()> func = std::bind(method, args...); exec(func); } template<class... Args> void performFuncWithoutReturn(void(*method)(Args...), Args... args) { std::function<void()> func = std::bind(method, args...); exec(func); } template<class Object, class T, class... Args> void asyncPerformStdObjectFunc(Object* object, T(_stdcall Object::*method)(Args...), Args... args) { std::function<void()> func = std::bind(method, object, args...); exec(func, false); } template<class Object, class T, class... Args> void asyncPerformObjectFunc(Object* object, T(Object::*method)(Args...), Args... args) { std::function<void()> func = std::bind(method, object, args...); exec(func, false); } template<class T, class... Args> void asyncPerformStdFunc(T(__stdcall *method)(Args...), Args... args) { std::function<void()> func = std::bind(method, args...); exec(func, false); } template<class T, class... Args> void asyncPerformFunc(T(*method)(Args...), Args... args) { std::function<void()> func = std::bind(method, args...); exec(func, false); } virtual bool EndPerformCmd() { return false; } virtual void processCmd() { std::unique_lock<std::mutex> lock(m_mtxCmd); auto iterDelCmd = m_vecDelCmd.begin(); while(iterDelCmd != m_vecDelCmd.end()) { if ((*iterDelCmd)->m_isDel) { delete (*iterDelCmd); m_vecDelCmd.erase(iterDelCmd); } else { iterDelCmd++; } } auto iterCmd = m_vecCmd.begin(); while(iterCmd != m_vecCmd.end()) { std::function<void()> *f = (std::function<void()>*)(*iterCmd)->getCmd(); if (f) { (*f)(); delete f; f = NULL; } if (!(*iterCmd)->m_isSync) { m_vecDelCmd.push_back((*iterCmd)); } (*iterCmd)->notify(); iterCmd=m_vecCmd.erase(iterCmd); if (EndPerformCmd()) { return; } } } protected: virtual void exec(std::function<void()> func,bool isSync=true) { std::function<void()> *f = new std::function<void()>(func); CQueueCmd *pCmd = new CQueueCmd(f, isSync); do { std::unique_lock<std::mutex> lock(m_mtxCmd); m_vecCmd.push_back(pCmd); } while (0); pCmd->wait(); if (isSync) { delete pCmd; } else { pCmd->m_isDel = true; } } private: template<class T> void wrap(std::function<T()> f, T* value) { *value = f(); } private: std::vector<CQueueCmd*> m_vecCmd; //函数调用命令参数 std::vector<CQueueCmd*> m_vecDelCmd; //删除命令队列 std::mutex m_mtxCmd; //互斥量 };