【问题标题】:Asio: how to get async data back into synchronous methodAsio:如何将异步数据恢复为同步方法
【发布时间】:2021-12-27 21:14:30
【问题描述】:

我将 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 是否提供更清洁的方式来执行此类操作?

谢谢

【问题讨论】:

  • 同步是指阻塞吗?
  • @JohnFilleau 是的

标签: c++ boost-asio


【解决方案1】:

如果你想同步两个线程,那么你必须使用同步原语(比如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();
}

【讨论】:

    猜你喜欢
    • 2021-04-12
    • 1970-01-01
    • 1970-01-01
    • 2019-12-26
    • 1970-01-01
    • 2018-02-24
    • 1970-01-01
    • 1970-01-01
    • 2015-03-29
    相关资源
    最近更新 更多