我正在使用boost :: asio。我写了一个负责从socket进行异步读取的类。 在我的应用程序中,io_service可以在一次应用程序运行期间多次停止和启动。 所以当服务停止时我不得不担心内存泄漏。 我找到了两个解决方案:
一个要求异步请求的类提供了一个用于在asio读取中使用的缓冲区的函数,它负责释放它。这是一个明显的解决方案,但我不喜欢它。将一个你不需要的参数传递给一个函数看起来真的很奇怪。
智能指针绑定到回调。这里的例子: http://pastebin.com/p8nQ5NFi
现在我正在使用第二种解决方案但是我感觉到,我正在发明一个轮子。异步调用中缓冲区清理的常见做法是什么?我的方法有什么隐藏的问题吗?
答案 0 :(得分:4)
shared_ptr
方法相当普遍。但是,不是将shared_ptr
作为附加参数传递给bind
,而是可以将shared_ptr
作为实例对象来代替this
。
boost::shared_ptr< my_class > ptr( this );
boost::asio::async_read( stream, buffer,
boost::bind( &my_class::read_handler, ptr,
boost::asio::placeholders::error
boost::asio::placeholders::bytes_transferred ) );
通常,由于实例将通过shared_ptr
进行管理,this
可能会或可能不会在boost::enable_shared_from_this
的上下文中进行管理,因此最好使用Boost.SmartPointer {{3 }}。当一个类继承自shared_from_this()
时,它会提供一个shared_ptr
成员函数,该函数会将有效的this
实例返回给class my_class: public boost::enable_shared_from_this< my_class >
{
void read()
{
boost::asio::async_read( stream, buffer,
boost::bind( &my_class::read_handler, shared_from_this(),
boost::asio::placeholders::error
boost::asio::placeholders::bytes_transferred ) );
}
};
boost::shared_ptr< my_class > foo( new my_class() );
foo->read();
。
foo.get()
在此代码段中,foo->shared_from_this()
和Protocol::AsyncReadMessage
都指向同一个实例。这有助于防止难以定位内存泄漏。例如,在原始示例代码中,AsyncReadHandler
如果AsyncReadMessage
的copy-constructor在尝试调用enable_shared_from_this
时抛出,则会发生内存泄漏。 Boost.Asio的enable_shared_from_this
和许多asynchronous TCP daytime server显示shared_ptr
在Boost.Asio中使用。为了更深入地理解,examples问题专门涵盖了异步Boost.Asio函数和Protocol::AsyncHelper
。
此外,在原始代码中,使AsyncHelper
成为模板类可能更容易,而不是使其成为具有模板成员函数的非模板化类。这将允许bind
接受协议,流和处理程序作为构造函数参数,将它们存储为成员变量。此外,它使{{1}}调用更容易阅读,因为它减少了需要传递的参数数量,并且由于成员函数不再是模板,因此无需指定其完整类型。 this是一个例子的快速传递。