我正在努力学习ASIO的提升,但我很难理解它。我想为服务器制作一个可扩展且高效的基础布局。
在以下URL中,有一个示例,其中设置了一个小型TCP服务器: http://www.boost.org/doc/libs/1_42_0/doc/html/boost_asio/tutorial/tutdaytime3/src.html
我不明白的是以下部分:
void start_accept()
{
tcp_connection::pointer new_connection =
tcp_connection::create(acceptor_.io_service());
acceptor_.async_accept(new_connection->socket(),
boost::bind(&tcp_server::handle_accept, this, new_connection,
boost::asio::placeholders::error));
}
void handle_accept(tcp_connection::pointer new_connection,
const boost::system::error_code& error)
{
if (!error)
{
new_connection->start();
start_accept();
}
}
start_accept()最终调用async_accept(),它在接收数据时调用它的处理程序。 并且处理程序在完成时调用start_accept()。
但是如果客户端在处理程序仍在运行时尝试连接会发生什么?是不是因为async_accept()不再听,所以无法处理请求?
如果我从错误的角度看问题,我希望你能指出我正确的方向。
答案 0 :(得分:1)
我认为您注意到处理程序在处理接受(async_accept
)后立即发布了新的new_connection->start()
操作:
void handle_accept(tcp_connection::pointer new_connection,
const boost::system::error_code& error)
{
if (!error)
{
new_connection->start(); // this posts connection specific asynch operations
start_accept(); // THIS POSTS THE ASYNC OPERATION AGAIN
}
}
您询问是否存在竞争条件(在内核收到连接的确切时刻,新的异步接受未处于暂挂状态。)
没有这样的竞争,因为内核将事件排入TCP / IP堆栈实现中。
事实上,请查看传统的select
/ poll
/ epoll
方法,类似地,当套接字更改状态时,您不会收到异步信号。相反,您可以在自己的闲暇时间进行轮询。
内核将对挂起事件的时间,缓冲区大小和数量有一些限制,因此如果您在一段时间内未能处理事件,它们可能会消失。
只要用户代码不能直接控制原始硬件,就不会有竞争条件,因为OS堆栈必须抽象低级别 中断请求(否则你将该操作系统称为ExoKernel)。