1.基础知识


std::future 是 C++ 标准库中的一个类模板,定义在 <future> 头文件中。它提供了一种异步操作的机制,用于获取异步任务的结果。

std::future 类模板表示一个未来可能会获得的值。你可以将一个异步任务交给 std::future 来管理,并在需要结果时获取该值。

下面是一些常用的 std::future 相关的类和函数:

  • std::future<T>std::future 类模板用于持有异步操作的结果。它模拟一个尚不存在的值,并提供一些方法来等待该值的完成并获取结果。
  • std::promise<T>std::promise 类模板用于设置异步操作的结果。你可以创建一个 std::promise 对象,并将它与一个 std::future 关联起来。通过调用 std::promise 对象的 set_value 方法,可以设置异步任务的结果,进而使关联的 std::future 对象可以获取到结果。
  • std::asyncstd::async 是一个函数模板,可以用于异步地执行函数或函数对象,并返回一个 std::future 对象以表示异步操作的结果。std::async 接受一个函数或函数对象作为参数,并创建一个异步任务来执行该函数或函数对象。
  • std::future_statusstd::future_status 是一个枚举类型,用于表示 std::future 对象的状态。它定义了三个值:deferred(延迟执行)、ready(已就绪)和 timeout(超时)。
  • std::shared_future<T>std::shared_futurestd::future 的共享版本。与 std::future 不同,std::shared_future 可以被多个线程共享,并且可以被拷贝。

使用 std::future,你可以在一个线程中启动一个异步任务,并在另一个线程中等待它的完成并获取结果。这提供了一种方便和高效的方式来处理并发编程中的异步操作。

请注意,<future头文件同时还包含其他相关的类和函数,比如 std::packaged_taskstd::asyncstd::when_all 等。你可以阅读相关的文档和参考资料来深入了解这些内容。

2. 举例实现

void processFrames() {
  if (options_.use_async_reproj && cams_->numCameras() > 1) {
    // 启动异步任务并且等待所有任务完成
    std::vector<std::future<void>> reproj_workers;
    for (size_t camera_idx = 0; camera_idx < cams_->numCameras(); ++camera_idx) {
      auto func = std::bind(&Reproj::reproFrames, reprojectors_.at(camera_idx).get(),
                            new_frames_->at(camera_idx), overlap_kfs_.at(camera_idx), trash_points.at(camera_idx));
      reproj_workers.push_back(std::async(std::launch::async, func));
    }

    // 等待所有异步任务完成
    for (auto& worker : reproj_workers) {
      worker.get();
    }
  } else {
    // 同步执行任务
    for (size_t camera_idx = 0; camera_idx < cams_->numCameras(); ++camera_idx) {
      reproj_.at(camera_idx)
          ->reprojFrames(new_frames_->at(camera_idx), overlap_kfs_.at(camera_idx), trash_points.at(camera_idx));
    }
  }
}