c++ - 从其处理程序或处理程序 dtor 中销毁 boost::asio 计时器是否安全?

标签 c++ boost boost-asio

在我们的产品中,我们的代码基本上可以简化为以下功能:

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

void DelayedCall(
    boost::asio::io_service& io,
    boost::asio::steady_timer::duration delay,
    std::function<void()> f)
{
    auto timer = std::make_shared<boost::asio::steady_timer>(io, delay);
    timer->async_wait(
        [timer, f](boost::system::error_code const&)
        {
            // Probably it's ok to do even this:
            //timer.reset();
            f();
        }
    );
}

为简单起见,假设 io 对象具有全局生命周期。

如您所见,计时器对象将在处理程序的析构函数中被销毁。

当我想到这个问题时,我注意到计时器中有一些引用正在执行 处理程序,反之亦然。我知道定时器析构函数将在所有异步等待处理程序上调用取消,但这无关紧要,因为处理程序已经在执行并且无法取消。

现在我认为计时器对象只是在时机成熟时将post() 的处理程序发送给io_service,因此计时器和处理程序彼此独立。然而快速调查 asio 源代码的尝试失败了,所以我仍然不确定我们的代码是否正确。

我没有在文档中找到任何相关信息 here也不here .

最佳答案

这对于所有 I/O 对象都是安全且定义明确的。


Boost.Asio 努力支持使用shared_ptr延长对象的生命周期,例如 steady_timer , 通过绑定(bind) shared_ptr 至少与一系列异步操作一样长将对象放入处理程序。 documentation备注:

[...] permits programs to simplify their resource management by using shared_ptr<>. Where an object's lifetime is tied to the lifetime of a connection (or some other sequence of asynchronous operations), a shared_ptr to the object would be bound into the handlers for all asynchronous operations associated with it.

为了支持这一点,启动函数按值接受处理程序,而 Boost.Asio 负责维护处理程序的有效性。实现可以复制处理程序,并且保证销毁所有拷贝:

  • 处理程序被调用后立即
  • io_service被摧毁
  • io_service::service拥有处理程序的人通过 shutdown_service() 关闭

requirements on asynchronous operations documentation状态:

Arguments to initiating functions will be treated as follows:

— If the parameter is declared as a const reference or by-value, the program is not required to guarantee the validity of the argument after the initiating function completes. The implementation may make copies of the argument, and all copies will be destroyed no later than immediately after invocation of the handler.

关于c++ - 从其处理程序或处理程序 dtor 中销毁 boost::asio 计时器是否安全?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35507956/

相关文章:

c++ - scanf在c++中的表示是什么

c++ - ubuntu 中是否有库的默认路径?

c++ - 在哪里使用 boost::asio 实现协议(protocol)?

在线程中运行的 C++ UDP 服务器 io_context 在工作开始之前退出

c++ - asio::async_write 和 strand

c++ - 在 C++ 中保证临时的生命周期?

c++ - 为字符类型的字符串赋值

c++ - 在此函数中通过引用传递参数

c++ - 删除 .. 在 boost filesystem::complete

c++ - BOOST_DATA_TEST_CASE是否始终要求 sample 的可打印性?