c++ - 如果 basic_waitable_timer 在仍有异步操作等待时被破坏怎么办?

标签 c++ boost boost-asio

如果 basic_waitable_timer 在仍有异步操作等待时被销毁怎么办?是否在任何地方记录了该行为?

最佳答案

当一个IO对象,比如basic_waitable_timer , 被摧毁, 它的 destructor将在 IO 对象的服务上调用 destroy()(不要与 io_service 混淆),传递 IO 对象的实现。 basic_waitable_timer 的服务是 waitable_timer_service并满足 WaitableTimerService类型要求。 WaitableTimerService 的要求定义了 destroy() 取消异步等待操作的后置条件,使它们尽快完成,并且取消操作的处理程序将传递错误代码 boost: :asio::error::operation_aborted.

service.destroy(impl); → Implicitly cancels asynchronous wait operations, as if by calling service.cancel(impl, e).

service.cancel(impl, e); → Causes any outstanding asynchronous wait operations to complete as soon as possible. Handlers for cancelled operations shall be passed the error code error::operation_aborted. Sets e to indicate success or failure.

请注意,已经排队等待调用的操作的处理程序不会被取消,并且会有一个反射(reflect)操作成功的 error_code


这是一个完整的例子demonstrating这种行为:

#include <iostream>
#include <boost/asio.hpp>
#include <boost/asio/steady_timer.hpp>

void demo_deferred_completion()
{
  std::cout << "[demo deferred completion]" << std::endl;
  boost::asio::io_service io_service;
  auto wait_completed = false;

  // Use scope to force lifetime.  
  {
    // Create the timer and initiate an async_wait operation that
    // is guaranteed to have expired.
    boost::asio::steady_timer timer(io_service);

    // Post a ready-to-run no-op completion handler into the io_service.
    // Although the order is unspecified, the current implementation
    // will use a predictable order.
    io_service.post([]{});

    // Initiate an async_wait operation that will immediately expire.
    timer.expires_at(boost::asio::steady_timer::clock_type::now());
    timer.async_wait(
        [&](const boost::system::error_code& error)
        {
          std::cout << "error: " << error.message() << std::endl;
          assert(error == boost::system::error_code()); // Success.
          wait_completed = true;          
        });

    // While this will only run one handler (the noop), it will
    // execute operations (async_wait), and if they are succesful
    // (time expired), the completion handler will be posted for
    // deferred completion.
    io_service.run_one();
    assert(!wait_completed); // Verify the wait handler was not invoked.
  } // Destroy the timer.

  // Run the handle_wait completion handler.
  io_service.run();
  assert(wait_completed);
}

void demo_cancelled()
{
  std::cout << "[demo cancelled]" << std::endl;
  boost::asio::io_service io_service;

  // Use scope to force lifetime.
  {
    boost::asio::steady_timer timer(io_service);

    // Initiate an async_wait operation that will immediately expire.
    timer.expires_at(boost::asio::steady_timer::clock_type::now());
    timer.async_wait(
        [](const boost::system::error_code& error)
        {
          std::cout << "error: " << error.message() << std::endl;
          assert(error ==
                 make_error_code(boost::asio::error::operation_aborted));
        });
  } // Destroy the timer.

  // Run the handle_wait completion handler.
  io_service.run();
}

int main()
{
  demo_deferred_completion();
  demo_cancelled();
}

输出:

[demo deferred completion]
error: Success
[demo cancelled]
error: Operation canceled

关于c++ - 如果 basic_waitable_timer 在仍有异步操作等待时被破坏怎么办?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26397269/

相关文章:

c++ - 在 OSX 上相当于 Windows 的 QueryPerformanceCounter 是什么?

c++ - 2 第 3 方 C 和 C++ 库具有与 Object 相同的类和结构名称,因此我得到对 'Object' 的引用是不明确的错误

c++ - Boost asio,单个 TCP 服务器,多个客户端

c++ - boost vector 的问题

c++ - 如何将组合的 Asio 操作与 C++20 协程一起使用以返回值?

c++ - 从命名空间调用方法 - 声明标识符

c++ - 如何确定 boost::any 是否包含文字字符串?

c++ - 检查顶点之间的平行边 : edge_range does not work with directed graph

C++ Boost - 没有找到接受类型为 'boost::filesystem::path' 的右手操作数的运算符

c++ - boost::asio::io_service 检查是否为空