#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;
}
std::packaged_task传递任务
最后编辑于 :
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。
推荐阅读更多精彩内容
- 在上一篇文章中我们介绍了如何自定义简单的任务。本文将通过如下四个简单任务来说明任务之间的依赖关系。 可以使用Tas...
- 进程、UI线程: 应用第一次启动时,会启动一个新的进程,该进程用应用的包名作为进程名(获取当前进程id的方法是:a...
- Android 启动模式--任务(Task)--桟 的误区 写这篇文章是因为前几天的一次面试,面试官说Single...
- 什么是任务栈(Task) 官方文档是这么解释的 任务是指在执行特定作业时与用户交互的一系列 Activity。 这...
- 昨天心理学课本知识学习的是如何和咨询者建立关系,由此联想到之前我在简书上写的一篇文章《如何管理朋友圈上千好...