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

 

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

 

我们知道,服务器并发模型通常可分为单线程和多线程模型,这里的线程通常是指“I/O线程”,即负责I/O操作,协调分配任务的“管理线程”,而实际的请求和任务通常交由所谓“工作者线程”处理。通常多线程模型下,每个线程既是I/O线程又是工作者线程。所以这里讨论的是,单I/O线程+多工作者线程的模型,这也是最常用的一种服务器并发模型。我所在的项目中的server代码中,这种模型随处可见。它还有个名字,叫“半同步/半异步“模型,同时,这种模型也是生产者/消费者(尤其是多消费者)模型的一种表现。

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

 

1 模型架构

 

 

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
        其他事件;     
}

  

伪码可能写的不太好,其实就是基本的epoll使用。

但要注意和线程池的配合使用,如果线程池取不到空闲的工作者线程,还需要做一些处理。

 

2.2 线程池实现要点

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

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

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

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

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

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

 

另外的变体:

 

io 线程把网络包,放到 Receive共享内存 里面 或者  Receive mq 里面,让  Receive 共享内存 或者  Receive mq 放到全局里面,让所有 工作证线程和 io 线程都可以访问。 io 线程把网络包放到  Receive mq 或者 Receive  共享内存里面以后,往有名管道里面写一个空字节,通知 工作者线程。工作者线程用锁或者 信号量,来互斥从  Receive mq 或者  Receive 共享内存里面取出来。处理完成之后放到 放到 send 共享内存 里面 或者  send mq 里面去,然后通知 io 线程,发送到网络里面去。

上面一种情况,达到工作者线程最大值时,不应再继续创建新线程, 则等待一小段时间并重试 ,放到 mq 或者共享内存里面 ,已经接受了用户的请求, 这个时延的产生就让空闲的 工作者线程有空来处理。这样不用重试。

 

转载于:https://www.cnblogs.com/door-hinges/p/4368259.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值