面试题答案
一键面试1. 资源管理策略
- 智能指针:使用
std::shared_ptr
或std::unique_ptr
来管理动态分配的资源。std::shared_ptr
适用于需要在多个地方共享资源的场景,而std::unique_ptr
适用于资源所有权明确唯一的情况。在异步操作中,将相关资源封装在智能指针内,确保当最后一个指向资源的指针被销毁时,资源能被正确释放。 - RAII(Resource Acquisition Is Initialization):遵循RAII原则,在对象构造时获取资源,在对象析构时释放资源。例如,自定义一个类来管理特定资源,在类的构造函数中分配资源,在析构函数中释放资源。这样在异步操作的生命周期内,资源能得到有效的管理。
- 连接跟踪:对于异步I/O操作涉及的连接(如socket连接),维护一个连接的跟踪列表。当连接完成或出错时,从列表中移除该连接,并释放相关资源。这有助于确保所有连接资源都能被正确清理,避免句柄泄露。
2. 代码实现示例
以下是一个使用 std::shared_ptr
和RAII管理资源的简单示例,展示如何在Boost.Asio的异步I/O处理中避免内存泄漏和句柄泄露:
#include <iostream>
#include <boost/asio.hpp>
#include <memory>
class Session : public std::enable_shared_from_this<Session> {
public:
Session(boost::asio::io_context& ioContext) : socket_(ioContext) {}
boost::asio::ip::tcp::socket& socket() {
return socket_;
}
void start() {
auto self(shared_from_this());
boost::asio::async_read_until(socket_, boost::asio::dynamic_buffer(buffer_), '\n',
[this, self](boost::system::error_code ec, std::size_t length) {
if (!ec) {
std::string message;
std::istream is(&buffer_);
std::getline(is, message);
std::cout << "Received: " << message << std::endl;
// 这里可以进行响应的处理和发送
boost::asio::async_write(socket_, boost::asio::buffer("Response\n"),
[this, self](boost::system::error_code ec, std::size_t /*length*/) {
if (!ec) {
// 继续下一次读取
start();
} else {
std::cerr << "Write error: " << ec.message() << std::endl;
}
});
} else {
std::cerr << "Read error: " << ec.message() << std::endl;
}
});
}
private:
boost::asio::ip::tcp::socket socket_;
boost::asio::streambuf buffer_;
};
class Server {
public:
Server(boost::asio::io_context& ioContext, unsigned short port)
: acceptor_(ioContext, boost::asio::ip::tcp::endpoint(boost::asio::ip::tcp::v4(), port)),
socket_(ioContext) {
startAccept();
}
private:
void startAccept() {
auto newSession = std::make_shared<Session>(acceptor_.get_executor().context());
acceptor_.async_accept(newSession->socket(),
[this, newSession](boost::system::error_code ec) {
if (!ec) {
newSession->start();
} else {
std::cerr << "Accept error: " << ec.message() << std::endl;
}
startAccept();
});
}
boost::asio::ip::tcp::acceptor acceptor_;
boost::asio::ip::tcp::socket socket_;
};
int main() {
try {
boost::asio::io_context ioContext;
Server server(ioContext, 12345);
std::vector<std::thread> threads;
for (std::size_t i = 0; i < std::thread::hardware_concurrency(); ++i) {
threads.emplace_back([&ioContext]() { ioContext.run(); });
}
for (auto& thread : threads) {
thread.join();
}
} catch (std::exception& e) {
std::cerr << "Exception: " << e.what() << std::endl;
}
return 0;
}
在上述代码中:
Session
类继承自std::enable_shared_from_this
,使用std::shared_ptr
来管理其自身实例,确保在异步操作的回调中对象不会在操作完成前被销毁。Server
类在接受新连接时,使用std::make_shared
创建Session
对象,利用智能指针的自动内存管理特性避免内存泄漏。- 整个程序通过RAII原则管理
boost::asio::io_context
、boost::asio::ip::tcp::acceptor
和boost::asio::ip::tcp::socket
等资源,在对象析构时自动释放相关句柄,避免句柄泄露。