我的代码中遇到了一个问题。
当连接完成时,每个连接都有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;
}
感谢您的帮助。
答案 0 :(得分:1)
根据this page boost :: asio :: buffer不拥有它指向的内存,因此你new[]
的缓冲区因为没有匹配的delete[]
而泄漏。< / p>
同样,根据该页面,您有责任确保它保持活着,然后再delete[]
。
答案 1 :(得分:1)
在工作线程中,你在每个循环中分配内存,但是你从不释放它。
您可以使用smart pointers,也可以将指针作为参数传递给async write habndler函数并将其释放。
答案 2 :(得分:1)
写缓冲区的内存管理看起来很好。 CConnection
和CConnection::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
操作。考虑在worker
和handle_write
之间同步状态,并在handle_write
内设置关闭状态。