在我们的产品中,我们的代码可以简化为基本功能:
#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
对象具有全局生命周期。
正如您所见,计时器对象将在处理程序的析构函数中被销毁。
当我想到这个问题时,我要小心定时器中的一些引用执行处理程序,反之亦然。我知道timer析构函数会在所有异步等待处理程序上调用cancel,但这与处理程序已经执行并且无法取消无关。
现在我认为,当时间到来时,计时器对象只是post()
io_service
的处理程序,因此计时器和处理程序彼此独立。尽管如此,快速尝试调查asio源代码失败了,所以我仍然不确定我们的代码是否正确。
答案 0 :(得分:2)
这对所有I / O对象都是安全且定义良好的。
Boost.Asio已经努力支持使用shared_ptr
来延长对象(例如steady_timer
)的生命周期,使其至少与通过绑定{的一系列异步操作一样长。 {1}}将对象转换为处理程序。 documentation注释:
[...]允许程序使用
shared_ptr
简化其资源管理。如果对象的生命周期与连接的生命周期(或某些其他异步操作序列)相关联,则对象的shared_ptr<>
将绑定到与其关联的所有异步操作的处理程序中。 / p>
为了支持这一点,启动函数按值接受处理程序,Boost.Asio负责维护处理程序的有效性。实现可以制作处理程序的副本,并保证所有副本都被销毁:
shared_ptr
被销毁io_service
通过shutdown_service()
requirements on asynchronous operations documentation州:
启动功能的参数将被视为如下:
- 如果参数声明为const引用或by-value,则在启动函数完成后,程序不需要保证参数的有效性。实现可以创建参数的副本,并且所有副本将在不迟于调用处理程序之后立即销毁。
答案 1 :(得分:0)
当<uses-permission android:name="android.permission.MEDIA_CONTENT_CONTROL"/>
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAG"/>
引用计数器变为0时,计时器将被销毁,并且当shared_ptr
所属的关闭将被销毁时,将发生这种情况。因此以这种特殊方式使用它是安全的。但请注意,如果您更改将计时器传递给lambda的方式,例如通过引用shared_ptr
或移动[&timer]
,则此代码将崩溃,因为复制时没有[timer = std::(move(timer))]
引用递增计时器将在你的处理程序范围出口处销毁。