Asio:如何将异步数据返回到同步方法

Asio: how to get async data back into synchronous method

我将 asio 用于异步 io,但有时我想“逃离”异步世界并将我的数据返回到常规同步世界。

例如,假设我有一个 std::deque<string> _data 在我的异步进程中使用(在单个线程中总是在后台 运行),并且我是否创建了异步函数从中读取/写入。

从另一个线程以同步方式从这个双端队列中读取的“自然”方式是什么? 到目前为止,我已经使用原子学来做到这一点,但这感觉有点“错误”。 例如:

std::string getDataSync()
{
std::atomic<int> signal = 0;
std::string str;

asio::post(io_context, [this, &signal, &str] { 
str = _data.front();
_data.pop_front();
signal = 1;
});

while(signal == 0) { }
return str;

}
  1. 这样做可以吗?
  2. asio 是否提供更清洁的方法来执行此类操作?

谢谢

如果要同步两个线程,则必须使用同步原语(如std::atomic)。 Asio 不提供更高级的原语,但 STL(和 boost)充满了它。对于您的简单示例,您可能希望使用 std::futurestd::promise 将双端队列的顶部项目移动到另一个线程。

这是一个小例子。我假设您不想直接从另一个线程访问双端队列,而只是访问最上面的项目。我还假设您在另一个线程中 运行 boost::asio::run

inline constexpr std::string pop_from_queue() { return "hello world"; }

int main() {
  auto context = boost::asio::io_context{};

  auto promise = std::promise<std::string>{};
  auto result = promise.get_future();
  boost::asio::post(context,
                    [&promise] { promise.set_value(pop_from_queue()); });

  auto thread = std::thread{[&context] { context.run(); }};
  std::cout << result.get(); // blocking
  thread.join();
}