【问题标题】:Asio reading stream_file asynchronously fails with coroutines and alternativesAsio 异步读取 stream_file 因协程和替代方案而失败
【发布时间】:2022-01-08 13:21:55
【问题描述】:

我正在使用 Boost.Asio 1.78,我无法将file_stream::async_read_some 与任何方法一起使用并使其在 Asio 中工作。

对于 co_await,它会抛出一个 22, Invalid argument,对于任何替代方法,它都不会运行。我使用的是 Ubuntu 20.04,我从 https://github.com/quickemu-project/quickemu 安装了文件 IO 的 liburing

这是读取文件协程:

boost::asio::awaitable<boost::container::vector<std::byte>> read_file_async(
   boost::asio::any_io_executor & exe, 
   const std::filesystem::path & p) { 
   using boost::asio::use_awaitable;
   boost::asio::stream_file file(exe, p.c_str(), 
                                 boost::asio::file_base::read_only | boost::asio::file_base::exclusive);

   if (!file.is_open()) {
     throw std::runtime_error(fmt::format("Could not open {}", p._c_str()));
   }
   constexpr std::size_t block_size = 1024 * 1024 * 2; 
   boost::container::vector<std::byte> buf(block_size, boost::container::default_init); 
   std::size_t curr_pos = 0; 
   std::size_t bytes_read = 1; 
   std::vector<std::byte> v(block_size);
   while (bytes_read > 0) {
       try {
         bytes_read = co_await file.async_read_some(boost::asio::buffer(buf.data() + curr_pos,
                                                                        buf.size() - curr_pos),
                                                    use_awaitable);
         curr_pos += bytes_read;
         if (curr_pos == buf.size())
           buf.resize(buf.size() * 2, boost::container::default_init);
       }
       catch (const boost::system::system_error & e) {
         fmt::print("{}\n", e.what());
         throw;
       }
   }
   buf.resize(curr_pos, boost::container::default_init);
   buf.shrink_to_fit();
   co_return std::move(buf);
 }

这是调用读取文件协程的代码:

boost::asio::io_context ctx;
auto the_task =
     [&](std::filesystem::path p) -> boost::asio::awaitable<void> {
       boost::asio::any_io_executor executor = co_await boost::asio::this_coro::executor;
       auto file_contents = co_await read_file_async(executor, p);
   };
  for (const auto &file_path : rng)
    boost::asio::co_spawn(ctx, the_task(file_path), boost::asio::detached);
  ctx.run();

【问题讨论】:

    标签: c++ boost c++20 coroutine asio


    【解决方案1】:

    我遇到了一个问题:file_stream::async_read_somefile_stream::async_write_some 的完成处理程序没有完成,因为 epoll 被禁用。

    我遵循了here设置 BOOST_ASIO_HAS_IO_URING 的说明,但没有设置BOOST_ASIO_DISABLE_EPOLL。现在我的完成处理程序,正确完成。

    【讨论】:

      猜你喜欢
      • 2015-06-29
      • 1970-01-01
      • 1970-01-01
      • 2021-04-08
      • 2022-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-12-27
      相关资源
      最近更新 更多