#ifndef _CREATEONCOSUME
#define _CREATEONCOSUME
#include <vector>
#include <memory>
#include <mutex>
#include <queue>
using namespace std;
template<typename T>
class CreateOnConsume {
public:
CreateOnConsume()
: m_forProduce(make_shared<vector<T> >()) {};
virtual void consumeEachVec(vector<T> &vec) = 0;
void push(T &t) {
lock_guard<mutex> lock(m_mtx);
m_forProduce->push_back(t);
};
void consumeAll() {
move2ForConsume();
while (!m_forConsume.empty()) {
auto &head = m_forConsume.front();
consumeEachVec(*head);
m_forConsume.pop();
}
};
protected:
shared_ptr<vector<T> > m_forProduce;
mutex m_mtx;
queue<shared_ptr<vector<T> > > m_forConsume;//?
void move2ForConsume() {
lock_guard<mutex> lock(m_mtx);
if (!m_forProduce->empty()) {
m_forConsume.push(m_forProduce);
m_forProduce = make_shared<vector<T> >();
}
};
};
#endif
子類只需要重載consumeEachVec即可。
生產過程的鎖粒度很低,只是往std::vector push。
消費過程的鎖只在move2ForCosume中作用。第一步判斷生產用的vector是否爲空,第二步搬運這個vector指針,第三步給生產者再創建一個vector。