#include<iostream>
#include<utility>
#include<future>
#include <queue>
template<typename T>
class threadsafe_queue{
public:
threadsafe_queue();
threadsafe_queue(const threadsafe_queue &);
threadsafe_queue &operator=(const threadsafe_queue &) = delete;
void push(T &&new_value);
bool try_pop(T & value);
std::shared_ptr<T> try_pop();
void wait_and_pop(T & value);
std::shared_ptr<T> wait_and_pop();
bool empty() const;
private:
mutable std::mutex mut;
std::queue<T> data_queue;
std::condition_variable data_cond;
};
template <typename T>
void threadsafe_queue<T>::push(T &&new_value) {//接受右值,但是,new_value在函数内并非右边值,push的时候仍需std::move转化
std::lock_guard<std::mutex> lk(mut);//std::packaged_task不可拷贝,只能移动
data_queue.push(std::move(new_value));
data_cond.notify_one();
}
template <typename T>
void threadsafe_queue<T>::wait_and_pop(T &value) {
std::unique_lock<std::mutex> lk(mut);
data_cond.wait(lk,[this]{
return !this->data_queue.empty();
});
value=data_queue.front();
data_queue.pop();
}
template <typename T>
bool threadsafe_queue<T>::try_pop(T &value) {
std::lock_guard<std::mutex> lk(mut);
if(!data_queue.empty())
return false;
else
{
value=data_queue.front();
data_queue.pop();
return true;
}
}
template <typename T>
std::shared_ptr<T> threadsafe_queue<T>::wait_and_pop() {
std::unique_lock<std::mutex> lk(mut);
data_cond.wait(lk,[this]{
return !this->data_queue.empty();
});
std::shared_ptr<T> res(std::make_shared<T>(std::move(data_queue.front())));
data_queue.pop();
return res;
}
template <typename T>
std::shared_ptr<T> threadsafe_queue<T>::try_pop() {
std::lock_guard<std::mutex> lk(mut);
if(!data_queue.empty())
return std::shared_ptr<T>();
std::shared_ptr<T> res(std::make_shared<T>(data_queue.front()));
data_queue.pop();
return res;
}
template <typename T>
bool threadsafe_queue<T>::empty() const {
std::lock_guard<std::mutex> lk(mut);
return data_queue.empty();
}
template <typename T>
threadsafe_queue<T>::threadsafe_queue() {
}
template <typename T>
threadsafe_queue<T>::threadsafe_queue(const threadsafe_queue &other) {
std::lock_guard<std::mutex> lk(other.mut);
data_queue=other.data_queue;
}
void worker1(){
std::cout<<"hello worker 1"<<std::endl;
}
void worker2(){
std::cout<<"hello worker 2"<<std::endl;
}
void product(threadsafe_queue<std::packaged_task<void()>> & queue){
queue.push(std::packaged_task<void()>(worker1));
queue.push(std::packaged_task<void()>(worker2));
}
void getdata(threadsafe_queue<std::packaged_task<void()>> & queue){
(*queue.wait_and_pop())();
(*queue.wait_and_pop())();
}
int main()
{
threadsafe_queue<std::packaged_task<void()>> queue;
std::thread t1(product,std::ref(queue));
std::thread t2(getdata,std::ref(queue));
t1.join();
t2.join();
return 0;
}
网友评论