码迷,mamicode.com
首页 > 编程语言 > 详细

浅谈服务器单I/O线程+工作者线程池模型架构及实现要点

时间:2014-08-01 12:45:51      阅读:283      评论:0      收藏:0      [点我收藏+]

标签:style   blog   http   使用   2014   问题   html   代码   

转自 http://www.cnblogs.com/ccdev/p/3542669.html

单I/O线程+多工作者线程的模型,这也是最常用的一种服务器并发模型。我所在的项目中的server代码中,这种模型随处可见。它还有个名字,叫“半同步/半异步“模型,同时,这种模型也是生产者/消费者(尤其是多消费者)模型的一种表现。

这种架构主要是基于I/O多路复用的思想(主要是epoll,select/poll已过时),通过单线程I/O多路复用,可以达到高效并发,同时避免了多线程I/O来回切换的各种开销,思路清晰,易于管理,而基于线程池的多工作者线程,又可以充分发挥和利用多线程的优势,利用线程池,进一步提高资源复用性和避免产生过多线程。

1 模型架构

bubuko.com,布布扣

2 实现要点

2.1 单I/O 线程epoll

实现单I/O线程的epoll模型是本架构的第一个技术要点,主要思想如下: 

单线程创建epoll并等待,有I/O请求(socket)到达时,将其加入epoll并从线程池中取一个空闲工作者线程,将实际的任务交由工作者线程处理。

伪码:

创建一个epoll实例;
while(server running)
{
    epoll等待事件;
    if(新连接到达且是有效连接)
    {
        accept此连接;
        将此连接设置为non-blocking;
        为此连接设置event(EPOLLIN | EPOLLET ...);
        将此连接加入epoll监听队列;
        从线程池取一个空闲工作者线程并处理此连接;
    }
    else if(读请求)
    {
        从线程池取一个空闲工作者线程并处理读请求;
    }
    else if(写请求)
    {
        从线程池取一个空闲工作者线程并处理写请求;
    }
    else
        其他事件;    
}

 

2.2 线程池实现要点

server启动时,创建一定数量的工作者线程加入线程池,如(20个),供I/O线程来取用;

每当I/O线程请求空闲工作者线程时,从池中取出一个空闲工作者线程,处理相应请求;

当请求处理完毕,关闭相应I/O连接时,回收相应线程并放回线程池中供下次使用;

若请求空闲工作者线程池时,没有空闲工作者线程,可作如下处理:

(1)若池中"管理"的线程总数不超过最大允许值,可创建一批新的工作者线程加入池中,并返回其中一个供I/O线程使用;

(2)若池中"管理"的线程总数已经达到最大值,不应再继续创建新线程, 则等待一小段时间并重试。注意因为I/O线程是单线程且不应被阻塞等待在此处,所以其实对线程池的管理应由一个专门的管理线程完成,包括创建新工作者线程等工作。此时管理线程阻塞等待(如使用条件变量并等待唤醒),一小段时间之后,线程池中应有空闲工作者线程可使用。否则server负荷估计是出了问题。 

浅谈服务器单I/O线程+工作者线程池模型架构及实现要点,布布扣,bubuko.com

浅谈服务器单I/O线程+工作者线程池模型架构及实现要点

标签:style   blog   http   使用   2014   问题   html   代码   

原文地址:http://www.cnblogs.com/notlate/p/3884410.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!