#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。 这...
- 昨天心理学课本知识学习的是如何和咨询者建立关系,由此联想到之前我在简书上写的一篇文章《如何管理朋友圈上千好...