C++ 异步编程

C++ Asynchronous programming

本文关键字:编程 异步 C++      更新时间:2023-10-16

我写了一个小型的同步C++应用程序。我已经到了需要调用一些异步运行的 API 的地步,在结果可用时调用一些已注册的回调。我遇到的问题是同步部分取决于来自异步调用的结果。

混合同步和异步代码时,最好推荐使用哪种方法?

进一步解释一下。我想调用异步 api,捕获结果,然后从那里继续我的 main(...

任何建议都是有帮助的。

我一直在考虑使用状态机。这是推荐的吗?

如果您使用的是已经实现异步作业的第三方 API,那么您所要做的就是遵循他们的规则。新的 C++11 异步线程内容(如 std::future/std::p romise )无济于事,因为您不需要在单独的线程中调用自己的任务,但您需要的是处理该 API 异步提供给当前线程的结果。

如果 API 没有同步操作选项,则必须以异步方式使用它。当您到达进行异步调用的点时,如果您需要结果来继续工作,那么您所能做的就是将回调处理程序作为该 API 异步调用的回调参数。在 C++11 中,您可以使用 lambda 作为回调处理程序。在这种情况下,您只需将代码从 API 调用的下方剪切并粘贴到 lambda 中,因为它以前是同步的。

该异步 API 提供的某些事件循环必须在某个地方无限运行,以确保您的工作线程处于活动状态并且可以调用异步回调。例如,在 boost::asio 中它是 io_service.run(),回调通过 io_service.post(callback) 回发到您的工作线程。

请参阅下面的示例。

// legacy code when you worked with sync API
void syncProcess()
{
   // code before call
   ResultType callResult=syncAPI.call(args);
   // code after call
}
// now you have async API
void asyncProcess()
{
   // code before call
   asyncAPI.call(args,
        [=](ResultType callResult)
        {
           // code after call
        }
   );
   /* the event loop can be here
    for example, it can be boost::asio::io_service::run() in case you're using boost::asio
   or something similar that keeps your main working thread alive and not locked
    if you use third party async API it must provide the event loop where async callbacks are invoked
  */
}

我认为期货最适合您的需求。有关详细信息,请查看 cplusplus.com。如果您需要一些代码示例,请随时在评论中提问。

我会创建一个condition variable和一个atomic bool。执行 API 调用并检查布尔值是否为真(如果是,则无法等待通知),如果不是,请等待条件变量。在回调中,您必须设置 bool 并通知条件变量。

当然,等待条件变量也需要互斥锁。