What is a better designpattern for creating a blocking bufferqueue, that uses resources efficiently in C++11/14 without too many allocs/moves? Using Queue<std::unique_ptr<Workitem>>
OR
Queue<Workitem> and with that hiding the resource management in the implementation (a bit like stl containers). Note, the second idea (Queue) is commented out. What are the implications of the commented out version also regarding heap/stack? And what about using std::unique_ptr<Queue<Workitem>> q?
I am not very good with c++, but regardless of the version, I can't really leak memory right? (reasonging: not new/delete -> no memoryleaks)
Code here:
#include <condition_variable>
#include <mutex>
#include <queue>
template <class T> class Queue {
public:
Queue(size_t size);
// push item to _queue if _queue.size() < _size
// else block
void push(T item);
// void push(std::unique_ptr<T> item);
// pop item if !_queue.empty()
// else block or return false after timeout
bool pop(T &item);
// bool pop(std::unique_ptr<T> &item);
private:
std::mutex _mutex;
std::size_t _size;
std::queue<T> _queue;
// std::queue<std::unique_ptr<T>> _queue;
std::condition_variable _condition_full;
std::condition_variable _condition_empty;
};
struct Workitem {
size_t idx;
void *workdetails;
};
int main() {
Queue<std::unique_ptr<Workitem>> q{4};
// Queue<Workitem> q{4};
// ??? std::unique_ptr<Queue<Workitem>> q{4} ???
std::unique_ptr<Workitem> w{};
// Workitem w{};
populate(w); // populate work item
q.push(std::move(w));
// later on ...
std::unique_ptr<Workitem> result;
// Workitem result;
q.pop(result);
consume(result); // consume work item
}
I can give the implementation if that helps, I just didn't want to clutter everything so I left it out. As a remark, the queue is used by threads. I use two queues for multiple worker threads and one writer thread to spread the load across cores.
cheers
Aucun commentaire:
Enregistrer un commentaire