//
// main.cpp
// threadsafe_queue
//
// Created by 蓝猫 on 2019/6/24.
// Copyright © 2019年 蓝猫. All rights reserved.
//
#include <iostream>
#include <queue>
#include <mutex>
#include <condition_variable>
#include <thread>
template<typename T>
class threadsafe_queue
{
private:
mutable std::mutex mutex_t;
std::queue<T> data_queue;
std::condition_variable cond;
public:
int size(){return data_queue.size();};
threadsafe_queue()=default;
threadsafe_queue(const threadsafe_queue& other)
{
std::unique_lock<std::mutex> lk(mutex_t);
data_queue=other.data_queue;
};
void push(T value)
{
std::unique_lock<std::mutex> lk(mutex_t);
data_queue.push(value);
printf("push %d \n",value);
cond.notify_one();
}
void wait_and_pop(T&value)
{
//printf("pop %d\n",value);
std::unique_lock<std::mutex> lk(mutex_t);
cond.wait(lk,[this]()->bool{return !data_queue.empty();});
//cond.wait(lk,!data_queue.empty());
value=data_queue.front();
printf("pop %d\n",value);
data_queue.pop();
}
std::shared_ptr<T> wait_and_pop()
{
std::unique_lock<std::mutex> lk(mutex_t);
cond.wait(lk,[this]()->bool{return !data_queue.empty();});
std::shared_ptr<T> res(std::make_shared<T>(data_queue.front()));
data_queue.pop();
return res;
}
bool empty() const
{
std::unique_lock<std::mutex> lk(mutex_t);
return data_queue.empty();
}
};
void fun_push(threadsafe_queue<int> &queue)
{
for(int i=0;i<10;i++)
{
queue.push(i);
}
}
void fun_pop(threadsafe_queue<int> &queue)
{
while(1)
{
int val;
queue.wait_and_pop(val);
}
}
threadsafe_queue<int> queue;
int main(int argc, const char * argv[])
{
std::thread t1(fun_push,std::ref(queue));
//std::cout<<queue.size()<<std::endl;
std::thread t2(fun_pop,std::ref(queue));
t1.join();
t2.join();
return 0;
}