gpt4 book ai didi

c++ - boost::asio 接受器避免内存泄漏

转载 作者:塔克拉玛干 更新时间:2023-11-03 02:12:00 27 4
gpt4 key购买 nike

使用 boost::asio 我使用 async_accept 接受连接。这很好用,但有一个问题,我需要一个如何处理它的建议。使用典型的 async_accept:

  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));
}

工作正常但有一个问题:Request 对象是用普通 new 创建的,因此它可能会内存“泄漏”。不是真正的泄漏,它只在程序停止时泄漏,但我想让 valgrind 开心。

当然有一个选项:我可以用 shared_ptr 替换它,并将它传递给每个事件处理程序。这将一直有效直到程序停止,当 asio io_service 停止时,所有对象将被销毁并且 Request 将被释放。但是这样我总是必须为 Request 激活 asio 事件,否则它将被破坏!我认为它是直接崩溃的方式,所以我也不喜欢这种变体。

UPD 第三种变体:Listener 保存事件连接的 shared_ptr 列表。看起来不错,除非找到更好的方法,否则我更喜欢使用它。缺点是:由于此模式允许在空闲连接上执行“垃圾收集”,因此它不安全:从 Listener 中删除连接指针将立即销毁它,当某些连接的处理程序在其他线程中处于事件状态时,这可能会导致段错误。在这种情况下,使用互斥锁无法解决这个问题,我们必须锁定几乎所有内容。

有没有办法让acceptor 以一种美观和安全的方式与连接管理一起工作?我很乐意听到任何建议。

最佳答案

使用此库时避免内存泄漏的典型方法是使用 shared_ptr , io_service documentation特意提到了这一点

Remarks

The destruction sequence described above 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. This works as follows:

When a single connection ends, all associated asynchronous operations complete. The corresponding handler objects are destroyed, and all shared_ptr references to the objects are destroyed. To shut down the whole program, the io_service function stop() is called to terminate any run() calls as soon as possible. The io_service destructor defined above destroys all handlers, causing all shared_ptr references to all connection objects to be destroyed.

根据您的情况,更改您的 Listener::handle_accept( ) 方法来获取 boost::shared_ptr<Request>范围。你的第二个问题

removing connection pointer from Listener will immediately destroy it, what can lead to segfault when some of connection's handler is active in other thread. Using mutex cant fix this cus in this case we must lock nearly anything.

通过继承 boost::enable_shared_from_this 得到缓解类中的模板:

class Listener : public boost::enable_shared_from_this<Listener>
{
...
};

然后当你分派(dispatch)处理程序时,使用 shared_from_this()而不是 this当绑定(bind)到 Listener 的成员函数时.

关于c++ - boost::asio 接受器避免内存泄漏,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12678702/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com