调用
socket.close()
不会销毁套接字。然而,应用程序可能需要管理操作和完成处理程序依赖的对象的生命周期,但这不一定是套接字对象本身。例如,考虑一个
client
类,它持有一个缓冲区、一个套接字,并具有一个带有完成处理程序
client::handle_read()
的单个未完成读取操作。可以
close()
并显式销毁套接字,但缓冲区和
client
实例必须保持有效,直到至少调用处理程序。
class client
{
...
void read()
{
io_service_.post([this]() {
async_read(*socket, boost::asio::buffer(buffer_);
boost::bind(&client::handle_read, this,
boost::asio::placeholders::error,
boost::asio::placeholders::bytes_transferred));
});
}
void handle_read(
const boost::system::error_code& error,
std::size_t bytes_transferred
)
{
}
void close()
{
io_service_.post([this]() {
socket_->close();
socket_.release(nullptr);
});
}
private:
boost::asio::io_service& io_service_;
std::unique_ptr<boost::asio::socket> socket_;
std::array<char, 512> buffer_;
...
}
应用程序负责管理操作和处理程序所依赖的对象的生命周期。聊天客户端示例通过等待
io_service.run()
在
join()
线程中返回,确保仅在不再使用时销毁
chat_client
实例。 参见
聊天客户端示例。
int main(...)
{
try
{
...
boost::asio::io_service io_service;
chat_client c(...);
std::thread t([&io_service](){ io_service.run(); });
...
c.close();
t.join();
}
catch (std::exception& e)
{
...
}
}
管理对象生命周期的一种常见习语是,让I/O对象由一个继承自enable_shared_from_this<>
的单个类来管理。当一个类继承自enable_shared_from_this
时,它提供了一个shared_from_this()
成员函数,返回一个有效的shared_ptr
实例来管理this
。将shared_ptr
的副本传递给完成处理程序,例如lambda中的捕获列表或作为bind()
的实例句柄进行传递,从而使I/O对象的生命周期至少延长到处理程序的生命周期。请参阅Boost.Asio异步TCP日间服务器教程,了解使用此方法的示例。