#pragma once
#include <queue>
#include <mutex>
#include <condition_variable>
#include <atomic>
template <typename T>
class ThreadSafeBlockQueue{
public:
ThreadSafeBlockQueue(){}
~ThreadSafeBlockQueue(){}
public:
void push(const T& element){
std::unique_lock<std::mutex> lock(_mutex);
_queue.push(std::move(element));
_empty_notify.notify_all();
}
void poptuple(std::vector<T>* array,const int& num)
{
this->nums = num;
std::unique_lock<std::mutex> lock(_mutex);
_empty_notify.wait(_mutex,[this](){return (!this->_queue.empty() && (this->_queue.size() >= this->nums));});
for (int i = 0; i < nums; i++)
{
auto ret = std::move(_queue.front());
_queue.pop();
array->push_back(ret);
}
}
T pop()
{
std::unique_lock<std::mutex> lock(_mutex);
_empty_notify.wait(_mutex,[this](){return !this->_queue.empty();});
auto ret = std::move(_queue.front());
_queue.pop();
return ret;
}
void clear(){
std::unique_lock<std::mutex> lock(_mutex);
while (!_queue.empty())
{
_queue.pop();
}
}
int size(){
std::unique_lock<std::mutex> lock(_mutex);
return _queue.size();
}
bool empty()
{
std::unique_lock<std::mutex> lock(_mutex);
return _queue.empty();
}
private:
std::atomic_int32_t nums;
std::mutex _mutex;
std::queue<T> _queue;
std::condition_variable_any _empty_notify;
};