【问题标题】:C++ Boost::Thread & Boost::ASIO memory leakC++ Boost::Thread & Boost::ASIO 内存泄漏
【发布时间】:2013-06-01 11:51:39
【问题描述】:

我的代码有一个问题。

连接完成后,每个连接都会有 10 兆内存泄漏。

连接正常,发送的数据包有效。

我不知道哪里错了。

工人函数:

    void worker(boost::shared_ptr<CConnection> connection) 
{
    boost::asio::ip::tcp::socket &socket = *(connection->socket);
    boost::asio::socket_base::non_blocking_io make_non_blocking(true);
    socket.io_control(make_non_blocking);

    while ( connection->close == false ) {

    char * buffer = new char[16]();
    buffer[0] = 16;
    buffer[4] = 1;
    buffer[8] = 1;
    buffer[12] = 1;

    boost::asio::async_write(socket, boost::asio::buffer(buffer, 16), boost::bind(handle_write, buffer));
    connection->close = true;
    } // while connection not to be closed
    LOG(INFO, "Connection finished!");
    socket.shutdown(boost::asio::ip::tcp::socket::shutdown_both);
    socket.close();
}

接受者代码:

void CCore::handle_accept(const boost::system::error_code& error) 
{
    if (error) {
        // accept failed
        LOG(ERROR, "Acceptor failed: " << error.message());
        return;
    }

    LOG(INFO, "Accepted connection from " << this->connection->endpoint.address().to_string() << ":" << this->connection->endpoint.port());

    this->connection->thread = boost::shared_ptr<boost::thread>(new boost::thread(worker, this->connection));

    this->connection = boost::shared_ptr<CConnection>(new CConnection());
    this->connection->master_io_service = this->io_service;
    this->acceptor->async_accept(*(this->connection->socket), this->connection->endpoint, boost::bind(&CCore::handle_accept, this, boost::asio::placeholders::error));
}

连接定义:

class CConnection {
  public:
    CConnection(void);
    boost::asio::io_service io_service;
    boost::shared_ptr<boost::asio::ip::tcp::socket> socket;
    boost::asio::ip::tcp::endpoint endpoint;
    boost::shared_ptr<boost::thread> thread;
    boost::asio::io_service *master_io_service;

    bool close;
};

包数据在handle_write中被释放:

void handle_write(char * buf)
{
 delete [] buf;
}

感谢您的帮助。

【问题讨论】:

    标签: c++ multithreading boost boost-asio


    【解决方案1】:

    根据this page boost::asio::buffer 不拥有它指向的内存,因此您new[] 向上的缓冲区泄漏,因为没有匹配的delete[]

    同样,根据该页面,您有责任确保它仍然活着,然后delete[]它。

    【讨论】:

    • 在句柄写入数据包时释放内存。
    【解决方案2】:

    在工作线程中,您在每个循环中分配内存,但您从不释放它。

    您可以使用smart pointers,或者将指针作为参数传递给异步写入habndler 函数并在那里释放它。

    【讨论】:

    • 内存在handle_write中被释放:delete [] buf;
    • @KacperFałat 那么你应该在问题中说明这一点,因为它并不明显。
    【解决方案3】:

    写缓冲区的内存管理看起来不错。 CConnectionCConnection::thread之间存在循环引用:

    • CConnection::thread 的生命周期取决于 CConnection,因为它是一个成员变量。
    • CConnection 的生命周期间接依赖于CConnection::thread,因为CConnection 被绑定为boost::thread 构造函数的参数。此参数的生命周期与boost::thread 对象的生命周期相关,而不是底层线程的执行。

      void CCore::handle_accept(...) 
      {
        ...
      
        this->connection->thread = 
          boost::shared_ptr<boost::thread>(new boost::thread(worker,
                                                             this->connection));
        ...
      }
      

    删除循环引用应该可以进行适当的清理。我不清楚这些对象的预期寿命是多少,因此我无法提供确切的解决方案。


    另外,一些 Boost.Asio 处理对我来说看起来有点尴尬。它看起来好像混合了同步和异步行为,这很难实现。在这种情况下,async_write 操作可能会在完成之前被取消。考虑在workerhandle_write 之间同步状态,并在handle_write 中设置关闭状态。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-03-18
      • 1970-01-01
      • 1970-01-01
      • 2012-09-22
      • 2014-11-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多