#include <queue>
#include <mutex>
#include <atomic>
#include <condition_variable>
#include <iostream>
template <typename T>
class BlockQue {
public:
~BlockQue(){
endBlock();
}
void addTask(T data){
//lock?
m_tasks.push(data);
m_task_cv.notify_all();
}
int getTask(T& data){
std::unique_lock<std::mutex> lock{ m_lock };
m_task_cv.wait(lock, [this]{
return m_end.load() || !m_tasks.empty();
});
if (m_tasks.empty()){
return -1;
}
data = std::move(m_tasks.front());
m_tasks.pop();
return 0;
}
void endBlock(){
if (!m_end.load()){
m_end.store(true);
m_task_cv.notify_all();
}
}
private:
std::atomic<bool> m_end{ false };
std::condition_variable m_task_cv;
std::queue<T> m_tasks;
std::mutex m_lock;
};
------------------------------------------------------------------------------
#include "blockque.hpp"
#include <thread>
#include <atomic>
#include <vector>
#include <iostream>
#include <Windows.h>
using namespace std;
class Test{
public:
void test(const int thId){
//while(m_run.load()){
while(true){
short val =0;
int ret = m_blockque[thId].getTask(val);
if(ret !=0){
break;
//cout<<"end blockque"<<endl;
//continue;
}
cout<<"thid["<<thId<<"] ==>"<<val<<endl;
}
}
Test(){
m_thpool.emplace_back( make_shared<thread>(&Test::test, this, 0));
m_thpool.emplace_back( make_shared<thread>(&Test::test, this, 1));
m_thpool.emplace_back( make_shared<thread>(&Test::test, this, 2));
}
~Test(){
//if (m_run.load()){
// m_run.store(false);
for(auto& val : m_blockque){
cout<<"ending"<<endl;
val.endBlock();
}
std::cout<<"===thread join======"<<std::endl;
for(auto& pThread : m_thpool){
if(pThread != nullptr && pThread->joinable()){
pThread->join();
}
}
m_thpool.clear();
//}
}
void testTask(){
int i=0;
for(auto& val : m_blockque){
val.addTask(i);
cout<<"input"<<i<<endl;
++i;
}
Sleep(1);
}
private:
BlockQue<short> m_blockque[3];
//std::atomic<bool> m_run{ true };
vector<shared_ptr<thread>> m_thpool;
};
int main()
{
Test test;
//Sleep(10);
test.testTask();
return 0;
}