#include #include template class threadsafe_queue { private: struct node { std::shared_ptr data; std::unique_ptr next; }; std::mutex head_mutex; std::unique_ptr head; std::mutex tail_mutex; node* tail; node* get_tail() { std::lock_guard tail_lock(tail_mutex); return tail; } std::unique_ptr pop_head() { std::lock_guard head_lock(head_mutex); if(head.get()==get_tail()) { return nullptr; } std::unique_ptr const old_head=std::move(head); head=std::move(old_head->next); return old_head; } public: threadsafe_queue(): head(new node),tail(head.get()) {} threadsafe_queue(const threadsafe_queue& other)=delete; threadsafe_queue& operator=(const threadsafe_queue& other)=delete; std::shared_ptr try_pop() { std::unique_ptr old_head=pop_head(); return old_head?old_head->data:std::shared_ptr(); } void push(T new_value) { std::shared_ptr new_data( std::make_shared(std::move(new_value))); std::unique_ptr p(new node); node* const new_tail=p.get(); std::lock_guard tail_lock(tail_mutex); tail->data=new_data; tail->next=std::move(p); tail=new_tail; } };