服务器编程中的文件描述符(2)

  当结合epoll的水平触发方式来监听lisenfd的连接时,大量socket连接涌来如果不处理会塞满TCP的连接队列,listenfd会一直产生可读事件,将服务器陷入忙等待,用C++开源网络库muduo作者陈硕的做法是事先准备一个空闲的文件描述符,当产生EMFILE错误时就先关闭这个空闲文件,获得一个文件描述符名额,再accept拿到一个socket连接的文件描述符,随后立刻close,这样就优雅的断开了与客户端的连接,最后重新打开空闲文件,把”坑”填上,以备再次出现这种情况时使用。

//在程序开头先”占用”一个文件描述符

int idlefd = open("/dev/null", O_RDONLY | O_CLOEXEC);
…………

//然后当出现EMFILE错误的时候处理这个错误

peerlen = sizeof(peeraddr);
connfd = accept4(listenfd,  (struct sockaddr*)&peeraddr, &peerlen, SOCK_NONBLOCK | SOCK_CLOEXEC);

if (connfd == -1)
{
    if (errno == EMFILE)
    {
        close(idlefd);
        idlefd = accept(listenfd, NULL, NULL);
        close(idlefd);
        idlefd = open("/dev/null", O_RDONLY | O_CLOEXEC);
        continue;
    }
    else
        ERR_EXIT("accept4");
}

由于文件描述符涉及内容庞杂,此时仅作抛砖引玉。

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/5dc3d984f113a3a31d0e00a4b45189c2.html