背景

在 C++ 中使用一个可调用对象构造一个 std::thread 对象,即可创建一个线程;使用互斥量 std::mutex 来确保多个线程对共享数据的读写操作的同步问题;使用 std::condition_variable 来解决线程执行顺序的同步问题。

异步操作

①.同步操作:在发出一个方法调用时,在没有得到结果之前该调用就不返回。由调用者主动等待这个调用的结果。

②.异步操作:在发出一个方法调用之后,这个调用就直接返回了,没有返回结果。即当一个异步过程调用发出后,调用者不会立刻得到结果。

std::future

std::future 是一个类模板,用来保存一个异步操作的结果,即这是一个未来值,只能在未来某个时候进行获取。

①.get():等待异步操作执行结束并返回结果,若得不到结果就会一直等待。

②.wait():用于等待异步操作执行结束,但并不返回结果。

③.wait_for():阻塞当前流程,等待异步任务运行一段时间后返回其状态 std::future_status,状态是枚举值:

deferred:异步操作还没开始;

ready:异步操作已经完成;

timeout:异步操作超时。

std::async

std::async 是一个函数模板,用来启动一个异步任务。相对于 thread ,std::future 是更高级的抽象,异步返回结果保存在 std::future 中,使用者可以不必进行线程细节的管理。
std::async 有两种启动策略:
①.std::launch::async::函数必须以异步方式运行,即创建新的线程。
②.std::launch::deferred:函数只有在 std:async 所返回的期值的 get 或 wait 得到调用时才执行、并且调用方会阻塞至运行结束,否则不执行。
若没有指定策略,则会执行默认策略,将会由操作系统决定是否启动新的线程。

代码示例

#include "iostream"
#include "future"
using namespace std;

int getDataDemo()
{
  cout << "数据查询开始" << " threadID:" << this_thread::get_id() << endl;
  this_thread::sleep_for(chrono::seconds(5));//模拟耗时
  return 100;
}
int main()
{
  cout << "执行数据查询" << " threadID:" << this_thread::get_id() << endl;
  future<int> m_future = async(launch::async, getDataDemo);//异步执行
//  future<int> m_future = async(launch::deferred, getDataDemo);//延迟执行
//  future<int> m_future = async(getDataDemo);//默认策略
  future_status m_status;
  do 
  {
    m_status = m_future.wait_for(chrono::seconds(1));
    switch (m_status)
    {
    case std::future_status::ready:
      cout << "数据查询完成" << " threadID:" << this_thread::get_id() << endl;
      break;
    case std::future_status::timeout:
      cout << "数据查询中..." << " threadID:" << this_thread::get_id() << endl;
      break;
    case std::future_status::deferred:
      cout << "数据查询延迟" << " threadID:" << this_thread::get_id() << endl;
      m_future.wait();
      break;
    default:
      break;
    }
  }while (m_status != future_status::ready);
  
  int ret = m_future.get();
  cout << "数据查询结果:"<< ret << " threadID:" << this_thread::get_id() << endl;

  system("pause");
    return 0;
}

执行结果如下:
①.异步执行
在这里插入图片描述
②.延迟执行
在这里插入图片描述
③.默认策略
在这里插入图片描述

在这里插入图片描述


版权声明:本文为lizhichao410原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
原文链接:https://blog.csdn.net/lizhichao410/article/details/123732787