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;
}
- 这样做可以吗?
- asio 是否提供更清洁的方法来执行此类操作?
谢谢
如果要同步两个线程,则必须使用同步原语(如std::atomic
)。 Asio 不提供更高级的原语,但 STL(和 boost)充满了它。对于您的简单示例,您可能希望使用 std::future
和 std::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();
}
我将 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;
}
- 这样做可以吗?
- asio 是否提供更清洁的方法来执行此类操作?
谢谢
如果要同步两个线程,则必须使用同步原语(如std::atomic
)。 Asio 不提供更高级的原语,但 STL(和 boost)充满了它。对于您的简单示例,您可能希望使用 std::future
和 std::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();
}