1. 异步通信

1.1 异步变量

promise:

  • promise提供存储异步通信的值 , 再通过其对象创建的future异步获得结果

  • promise创建的一个对象只能用一次set_value设置传递值;也只能用一次get_future()获取future对象

  • 创建子线程时需要使用movepromise对象传给子线程

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模式后二者耗时相似