Chapter 4 多线程异步通信和并发计算
1. 异步通信
1.1 异步变量
promise:
-
promise提供存储异步通信的值 , 再通过其对象创建的future异步获得结果 -
promise创建的一个对象只能用一次set_value设置传递值;也只能用一次get_future()获取future对象 -
创建子线程时需要使用
move将promise对象传给子线程
future:
future对象的get()方法会阻塞等待promise::set_value()的值
代码示例:
#include <iostream>
#include <future>
#include <thread>
using namespace std;
void TestFuture(promise<string> p)
{
p.set_value("TestFuture value\n");
}
int main(int argc, char* argv[])
{
promise<string> p;/*异步传输变量存储*/
auto future{ p.get_future() };/*用来获取线程异步值获取*/
thread th(TestFuture, move(p));
cout << "future.get() = " << future.get();
th.join();
return 0;
}
1.2 异步调用函数
packaged_task:
- 包装函数为一个对象,可通过
get_future()获取future对象
代码示例:
#include <iostream>
#include <future>
#include <thread>
using namespace std;
string TestPack(const int index)
{
string r {__FUNCTION__};
r += " return";
return r;
}
int main(int argc, char* argv[])
{
packaged_task<string(const int)> task(TestPack);
auto result { task.get_future() };
thread th(move(task), 100);
cout << "result get = " << result.get();
th.join();
return 0;
}
1.3 阻塞超时
future对象的wait_for()方法会阻塞等待一段时间;如果返回结果为future_status::ready则说明收到信号;超时则返回future_status::timeout
1.4 创建异步线程
async关键词标记:
-
launch::deferred任务在其结果首次被请求时wait_for()和get()在调用线程上执行(不创建子线程) -
launch::async任务在一个不同的线程上执行(创建子线程),立刻执行
2. 并发计算
C++17:
通过std::for_each(std::execution::par,begin,end,lambda)实现
需要包含<algorithm>和<execution>两个头文件
CMAKE需要添加find_package(TBB REQUIRED)和target_link_libraries(YOUR_TARGET PRIVATE TBB::tbb)
C++17之前:
需要手动切片、手动管理线程池、手动确定边界
设置Release模式后二者耗时相似
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来源 雯欂の修仙笔记!