C++并发低级接口:std::thread和std::promise
std::thread和std::promise
相比std::async
,std::thread
就原始多了。thread一定会创建新线程(而不是像async那样创建的时候可能不会,后面才创建新线程(std::launch::deferred)),并且创建它的线程还必须指定以何种策略等待新线程。
#include <iostream>
#include <thread>
void task() {
for (int i = 0; i < 10; i++) {
std::cout << "A";
}
}
int main() {
std::thread td(task);
for (int i = 0; i < 10; i++) {
std::cout << "B";
}
td.join();
system("pause");
return 0;
}
这里首先std::thread td(task);
创建新线程异步输出"A",然后主线程输出"B",td.join()就是所谓的创建它的线程还必须指定以何种策略等待新线程,有两种策略可供选择:
- std::thread.join() 阻塞直到子线程结束
- std::thread.detach() 不阻塞。让它自由发挥。
虽然std::thread.detach()
可以不阻塞主线程,但是如果主线程结束那这些后台任务都会强行终止,比如你后台是下载任务,所以几乎没有直接用detach
的,都是配合后面的同步机制如std::condition_variable
。
这里也凸显了std::async
的高级和std::thread
的低级:在std::async
中我们可以对它的返回值即std::future
简单的调用get()
实现同步等待甚至能获取任务的结果,但是std::thread
就不行,要等待子线程结束或者获取子线程执行结果需要条件变量等同步机制。
std::promise
std::promise
独树一帜,它用于线程间传递值,其中std::promise.set_value
是设置值,std::promise.set_exception
是设置异常,注意两者不能同时设置。std::promise.get_future
则是返回一个std::future
。因为我们设置了值总会获取它吧,获取的方法就是get_future(),然后再get():
#include <iostream>
#include <thread>
#include <future>
void task(std::promise<int>& p) {
std::cout << "Retrieve value from another thread:" << p.get_future().get() << "\n";
}
int main() {
std::promise<int> p;
std::thread td(task,std::ref(p));
std::this_thread::sleep_for(std::chrono::seconds(3));
std::cout << "Task in main thread accomplished...\n";
p.set_value(1024);
td.join();
system("pause");
return 0;
}
程序先输出"Task in main thread accomplished..."再输出"Retrieve value from another thread:1024"。task线程中p.get_future().get()会阻塞当前线程直到promise已经设置值,即task线程会一直阻塞直到main线程执行
p.set_value(1024);
后才继续执行。
多说一点,其实std::promise和std::future都是多线程状态共享的方案,这两种不存在高级低级,只有std::async和std::thread有点高级低级之分。不过《C++标准库》中这样分类,加之std::future,std::promise分别用于std::async和std::thread的示例,我也只能照做了;)
最新文章
- LBS数据分析:使用地图展示统计数据——麻点图与麻数图
- who命令的总结
- 浅谈K-SVD
- Java:IO流之字节流InputStream、OutputStream详解
- 转 -- MVC+EF easyui dataGrid 动态加载分页表格
- HDU 4185 Oil Skimming
- 软交所--微软将对IE浏览器进行关键性安全更新
- 空间参考系统与WKT解析
- Android 架构艺术之MVP
- c语言几个松散的地方(不足的地方,不严谨的地方,它容易出错的地方)。
- nsqlookup_protocol_v1.go
- win 域
- [LeetCode] Random Pick with Blacklist 带黑名单的随机选取
- 初识spark的MLP模型
- Tomcat 部署及配置
- python之GIL官方文档 global interpreter lock 全局解释器锁
- python线程池(threadpool)模块使用笔记 .python 线程池使用推荐
- svn Mac
- php 去除所有空格 包括中文空格圆角空格
- python List使用
热门文章
- List转Datable(需区分对象充当List成员和数组充当List成员两种情况)
- elastic(6) mget
- 杀死tomcat进程
- 1-EasyNetQ介绍(黄亮翻译)
- MongoDB数据导入hbase + 代码
- 在Linux下adb连接不上android手机的终极解决方案
- Vbs 脚本编程简明教程之一
- 【摘自张宴的";实战:Nginx";】http auth baseic模块(打开页面需要密码验证)
- c# ??和运算符先后的问题
- Luogu 4363 [九省联考2018]一双木棋chess