当连接达到文件描述符的上限,此时没有可供你保存新连接套接字的文件描述符了,那么新来的连接就会一直放在accept队列中,于是呼应其可读事件就会一直触发读事件(因为你一直不读,也没办法读走它),这就是我们常常说的busy-loop.
如何解决Busy-Loop
//Acceptor构造函数
Acceptor::Acceptor(EventLoop* loop, const InetAddress& listenAddr, bool reuseport)
: loop_(loop),
acceptSocket_(sockets::createNonblockingOrDie(listenAddr.family())),
acceptChannel_(loop, acceptSocket_.fd()),
listenning_(false),
idleFd_(::open("/dev/null", O_RDONLY | O_CLOEXEC))
{
assert(idleFd_ >= 0);
acceptSocket_.setReuseAddr(true);
acceptSocket_.setReusePort(reuseport);
acceptSocket_.bindAddress(listenAddr);
acceptChannel_.setReadCallback(
std::bind(&Acceptor::handleRead, this));
}
...
void Acceptor::handleRead()
{
loop_->assertInLoopThread();
InetAddress peerAddr;
//FIXME loop until no more
int connfd = acceptSocket_.accept(&peerAddr);
if (connfd >= 0)
{
// string hostport = peerAddr.toIpPort();

当连接数达到文件描述符上限,新连接会停留在accept队列,引发持续的可读事件,形成busy-loop。muduo通过在Acceptor中设置一个空洞文件描述符idleFd_,在达到上限时关闭它以释放描述符,从而接纳新连接,并在新连接处理后重新获取空洞文件描述符,有效解决了这个问题。
最低0.47元/天 解锁文章
6098

被折叠的 条评论
为什么被折叠?



