c/c++ 多线程 等待一次性事件 packaged_task用法
多线程 等待一次性事件 packaged_task用法
背景:不是很明白,不知道为了解决什么业务场景,感觉std::asynck可以优雅的搞定一切,一次等待性事件,为什么还有个packaged_task。
用法:和std::async一样,也能够返回std::future,通过调用get_future方法。也可以通过future得到线程的返回值。
特点:
1,是个模板类,模板类型是个方法类型,比如double(int),有一个参数,类型是int,返回值类型是double。
std::packaged_task<double(int)> task(func);//func是个方法,有一个参数,类型是int,返回值类型是double
2,直接执行std::packaged_task的对象task时,不是异步执行,是在原来的线程上阻塞执行,也就是说,只有task执行结束后,后面的代码才能被执行,也就是说不是多线程执行。
std::packaged_task<std::string(int)> task1(call_texi);
std::future<std::string> ft1 = task1.get_future();
task1(100);//task1执行完成后,才能执行下面的打印输出的代码,不是在新的线程里执行task1(100)
std::cout << "111111111111111111111111111111" << std::endl;
3,作为线程的参数时,用std::ref。把task放在线程里后,就是异步执行了。
std::packaged_task<std::string(int)> task1(call_texi);
std::future<std::string> ft1 = task1.get_future();
std::thread t1(std::ref(task1), 100);
t1.detach();//task1(100)是异步执行,也就是在新的线程里执行。
std::cout << "111111111111111111111111111111" << std::endl;
代码:
#include <deque>
#include <mutex>
#include <future>
#include <thread>
#include <iostream>
#include <unistd.h>
#include <string>
//#include <utility>
std::mutex mut;
std::deque<std::packaged_task<std::string(int)>> tasks;
void manage_tasks(){
while(true){
sleep(1);
//std::cout << "please wait for a moument" << std::endl;
std::packaged_task<std::string(int)> task;
{
std::lock_guard<std::mutex> lg(mut);
if(tasks.empty()) continue;
std::cout << "----------------------not empty---------------" << std::endl;
task = std::move(tasks.front());
tasks.pop_front();
}
task(1);
//std::string s = task(10);
}
}
template<typename Call>
std::future<std::string> add_task(Call ca){
std::cout << "----------------------add_task---------------" << std::endl;
std::packaged_task<std::string(int)> task(ca);
std::future<std::string> ret = task.get_future();
std::lock_guard<std::mutex> lg(mut);
tasks.push_back(std::move(task));
return ret;
}
std::string call_texi(int i = 0){
std::cout << "-------------jiaoche---------------" << std::endl;
if(i == 1){
return "aaa";
}else{
return "bbb";
}
}
std::string call_zhuanche(int i){
std::cout << "zhuanche:" << i << std::endl;
return std::to_string(i);
}
int main(){
std::thread background_thread(manage_tasks);
background_thread.detach();
std::future<std::string> fut1 = add_task(call_texi);
std::cout << fut1.get() << std::endl;
std::future<std::string> fut2 = add_task(call_zhuanche);
std::cout << fut2.get() << std::endl;
pthread_exit(NULL);
}
编译方法:
g++ -g XXX.cpp -std=c++11 -pthread
运行结果:
----------------------add_task---------------
----------------------not empty---------------
-------------jiaoche---------------
aaa
----------------------add_task---------------
----------------------not empty---------------
zhuanche:1
1
代码分析:在队列里保存std::packaged_task,启动一个后台线程background_thread,上锁,监视队列里是否有了新的task,有了新的task,就取出来用右值赋值的方式,然后出队这个task,解锁。执行这个task。
迷惑点:
- add_task的调用时点,是可以知道传递什么参数的,但是调用add_task时,由于语法的限制不能够把参数传递给call_zhuanche方法或者call_taxi方法,只有在manage_tasks方法里调用task方法时,才能够传递参数,可是在这个时点,参数从哪里来???求大神指点!!!
c/c++ 学习互助QQ群:877684253
本人微信:xiaoshitou5854
c/c++ 多线程 等待一次性事件 packaged_task用法的更多相关文章
- c/c++ 多线程 等待一次性事件 std::promise用法
多线程 等待一次性事件 std::promise用法 背景:不是很明白,不知道为了解决什么业务场景,感觉std::async可以优雅的搞定一切的一次等待性事件,为什么还有个std::promise. ...
- c/c++ 多线程 等待一次性事件 异常处理
多线程 等待一次性事件 异常处理 背景:假设某个future在等待另一个线程结束,但是在被future等待的线程里发生了异常(throw一个异常A),这时怎么处理. 结果:假设发生了上面的场景,则在调 ...
- c/c++ 多线程 等待一次性事件 future概念
多线程 等待一次性事件 future概念 背景:有时候,一个线程只等待另一个线程一次,而且需要它等待的线程的返回值. 案例:滴滴叫车时,点完了叫车按钮后,叫车的后台线程就启动了,去通知周围的出租车.这 ...
- c/c++ 多线程 多个线程等待同一个线程的一次性事件
多线程 多个线程等待一个线程的一次性事件 背景:从多个线程访问同一个std::future,也就是多个线程都在等待同一个线程的结果,这时怎么处理. 办法:由于std::future只能被调用一次get ...
- c/c++ 多线程 一个线程等待某种事件发生
多线程 一个线程等待某种事件发生 背景:某个线程在能够完成其任务之前可能需要等待另一个线程完成其任务. 例如:坐夜间列车,为了能够不坐过站, 1,整夜保持清醒,但是这样你就会非常累,不能够睡觉. 2, ...
- iOS 开发多线程篇—GCD的常见用法
iOS开发多线程篇—GCD的常见用法 一.延迟执行 1.介绍 iOS常见的延时执行有2种方式 (1)调用NSObject的方法 [self performSelector:@selector(run) ...
- iOS开发多线程篇—GCD的常见用法
iOS开发多线程篇—GCD的常见用法 一.延迟执行 1.介绍 iOS常见的延时执行有2种方式 (1)调用NSObject的方法 [self performSelector:@selector(run) ...
- c#多线程中Lock()关键字的用法小结
本篇文章主要是对c#多线程中Lock()关键字的用法进行了详细的总结介绍,需要的朋友可以过来参考下,希望对大家有所帮助 本文介绍C# lock关键字,C#提供了一个关键字lock,它可以把一段 ...
- opencv学习之等待按键事件-waitKey函数
文章来源: https://mangoroom.cn/opencv/opencv-learning-waitKey.html 序 waitKey函数属于opencv函数里既常用又非常基础的函数,无论是 ...
随机推荐
- Ubuntu12.04下安ns-3.29及Ubuntu换源方法
目录 1.下载ns-3.29 2.安装gcc-4.9.2 3.编译.测试ns-3.29 第一种:更新,文章开头说的 第二种,更新源 主机型号:Ubuntu12.04 仿真环境版本:NS-3.29 安装 ...
- 巡风源码阅读与分析---view.py
巡风xunfeng----巡风源码阅读与分析 巡风是一款适用于企业内网的漏洞快速应急.巡航扫描系统,通过搜索功能可清晰的了解内部网络资产分布情况,并且可指定漏洞插件对搜索结果进行快速漏洞检测并输出结果 ...
- tensorflow、cuda、cudnn之间的版本对应关系
原文链接 tensorflow-gpu v1.9.0 | cuda9.0 | cuDNN7.1.4可行 | 备注:7.0.4/ 7.0.5/ 7.1.2不明确 tensorflow-gpu v1. ...
- RAC集群数据库连库代码示例(jdbc thin方式,非oci)
1.RAC集群数据库连库代码示例(jdbc thin方式,非oci):jdbc.driverClassName=oracle.jdbc.driver.OracleDriverjdbc.url=jdbc ...
- 我对SQL性能优化的看法,对我的文章有提议的欢迎评论!
影响你的查询速度的原因是什么? 网速不给力,不稳定. 服务器内存不够,或者SQL 被分配的内存不够. sql语句设计不合理 没有相应的索引,索引不合理 表数据过大没有有效的分区设计 数据库设计太2,存 ...
- ASP.NET Core SignalR中的流式传输
什么是流式传输? 流式传输是这一种以稳定持续流的形式传输数据的技术. 流式传输的使用场景 有些场景中,服务器返回的数据量较大,等待时间较长,客户端不得不等待服务器返回所有数据后,再进行相应的操作.这时 ...
- sql server 临时表(中) Tempdb监控
一. 监控概述 Tempdb库空间使用的一大特点,是只有一部分对象,例如用户创建的临时表.table变量等,可以用sys.allocation_units和sys.partitions这样的管理视图 ...
- Python爬虫入门教程 14-100 All IT eBooks多线程爬取
All IT eBooks多线程爬取-写在前面 对一个爬虫爱好者来说,或多或少都有这么一点点的收集癖 ~ 发现好的图片,发现好的书籍,发现各种能存放在电脑上的东西,都喜欢把它批量的爬取下来. 然后放着 ...
- Lottie 动画里有图片怎么办?设计师小姐姐也能帮你减少开发量!
一.序 Hi,大家好,我是承香墨影! Lottie 是 Airbnb 开源的一套跨平台的完整解决方案,设计师只需要使用 After Effectes (之后简称 AE)设计出动画之后,使用 Lotti ...
- 【Python3爬虫】selenium入门
selenium 是一个用于Web应用程序测试的工具.Selenium测试直接运行在浏览器中,就像真正的用户在操作一样.支持的浏览器包括IE(7, 8, 9, 10, 11),Mozilla Fire ...