使用boost :: asio我使用async_accept来接受连接。这很好,但有一个问题,我需要一个建议如何处理它。利用典型async_accept:boost :: asio acceptor避免内存泄漏
Listener::Listener(int port)
: acceptor(io, ip::tcp::endpoint(ip::tcp::v4(), port))
, socket(io) {
start_accept();
}
void Listener::start_accept() {
Request *r = new Request(io);
acceptor.async_accept(r->socket(),
boost::bind(&Listener::handle_accept, this, r, placeholders::error));
}
工作正常,但有一个问题:请求对象与普通新因此它可以内存“泄漏”创建。不是真的泄漏,它只在程序停止时泄漏,但是我想让012g幸福。
确定有一个选项:我可以将其替换为shared_ptr,并将其传递给每个事件处理程序。这将工作,直到程序停止,当asio io_service正在停止,所有对象将被销毁,请求将被free'd。但这样我总是必须有一个活跃的asio事件请求,否则它将被销毁!我认为它的直接方式崩溃,所以我不喜欢这个变种。
UPD第三种变体:Listener
将shared_ptr列表保存到活动连接。看起来不错,我更喜欢使用这个,除非找到更好的方法。缺点是:由于这个模式允许在空闲连接上进行“垃圾收集”,因此它不安全:从Listener中删除连接指针将立即销毁它,当某个连接的处理程序在其他线程中处于活动状态时,会导致segfault。在这种情况下,使用互斥锁无法解决这个问题,我们必须锁定几乎任何东西。
有没有办法使acceptor工作与连接管理一些美丽和安全的方式?我会很高兴听到任何建议。
这不是你的'Listener'类的设计问题,或者你的策略是用指针而不是函数对象来使用'bind',而不是'acceptor'类的问题? – Hurkyl
它不是一个函数对象=)但无论如何,我没有看到如何纯函数可以解决这个问题。 – PSIAlt
@PSIAlt请你详细说明为什么习惯'shared_ptr' /'enable_shared_from_this'方法不起作用?我不明白* active * asio事件的上下文。另外,如果'Request'没有创建它自己的异步调用链,并且将它的生命周期绑定到链上,那么其他对象是否维护'Request'对象的句柄? –