Reactor和Proactor模式简述

Reactor和Proactor模式

前言

  1. 如果让一个服务端服务多个客户端,可以来了一个客户,服务端就为这个客户发起的连接创建一个线程,但是当来了很多客户,服务端就要创建很多线程,每个客户完成自己的工作就会离开,此时服务端创建的线程就要销毁,这样就会创建然后销毁很多线程,造成资源浪费。
  2. 一个线程对应一个连接的方式不可取,那是不是可以想办法让一个线程对应多个连接呢?我们可以先创建一个线程池,来复用线程池里的线程,让线程池里的每个线程都可以对应多个连接。但是这也会有一个问题:一个线程对应一个连接的时候,这个线程一般要去read数据,但是如果当前连接没有数据可读,那这个线程就会阻塞在read操作上,那本来这个线程对应的其他连接就会一直等待。
  3. 线程池的问题在于线程不知道该连接有没有数据可读,一个比较笨的方法是将socket改成非阻塞的,让线程过一段时间就去询问该连接数据有没有准备好,这样反复去询问线程也很累啊(要消耗CPU),如果该线程对应的连接更多,那效率就会很低。
  4. 其实只要当该连接上有数据可读的时候通知对应的线程,我这里数据准备好了,你可以来读取了,IO多路复用就是这种思想。IO多路复用会使用一个系统调用函数来监听用户关心的连接,也就是可以用一个线程来监听许多连接,如果这些连接里有数据准备好了,这个线程就去读取这个数据,如果数据还没准备好,线程就阻塞在这个系统调用,此时这个系统调用对应着多个连接,就是多个连接中有任何一个连接数据准备好了,然后这个线程就去读这个连接的数据。区别于线程池的需要这个线程去询问每个连接是否有数据,这里线程只需要在所有对应的连接的外面等着,有一个连接数据准备好了这个线程就去读这个数据,读完之后再继续等着(阻塞),等所有对应连接中是否有数据准备好。

网上看了餐馆服务员吃饭的例子感觉很形象,这里简单说一下。

  1. 一个服务员对应一桌顾客
  2. 一个服务员对应多桌顾客:这个服务员在顾客点菜的时候就拿着菜单等着,等顾客点好,然后再去下一桌。
  3. 一个服务员对应多桌顾客:这个服务员让顾客点菜,然后服务员去服务其他桌顾客,期间这个服务员时不时的来询问点菜的顾客是否点好了。
  4. 一个服务员对应多桌顾客:这个服务员在大厅等着顾客点菜,哪个顾客点好菜了就去叫这个服务员,然后服务员处理好之后再去大厅等着。

Reactor

Reactor是什么

Reactor就是一种封装IO多路复用的高效的事件处理模式。

思想

将所有要处理的IO事件注册到一个中心IO多路复用器上,同时主线程阻塞在这个多路复用器上(这里就是实现一个线程在监听多个连接,当这个阻塞的线程被唤醒的时候,说明已经有一些连接已经准备好数据了);一旦有IO事件到来或者准备就绪,多路复用器返回并将相应IO事件分发到对应的处理器中。此时读写数据,接收新的连接都是由其他工作线程去做。

重要组成

  1. 多路复用器:由操作系统提供,在linux上一般是select, poll, epoll等系统调用,负责监听事件。
  2. 事件分发器:将多路复用器中返回的就绪事件分发到对应的处理函数中。
  3. 事件处理器:负责处理特定事件的处理函数。

工作流程

  1. 注册就绪事件
  2. 事件分发器等待事件
  3. 事件到来分发器调用事件处理器
  4. 事件处理器完成实际的读操作,处理读到的数据,注册新的事件,然后返回控制权

参考:linux高性能服务器上的流程
在这里插入图片描述

几种实现

这里Reactor的数量可以有多个,事件处理器也可以是单线程,也可以是多线程。所以有几种实现方式。

单Reactor单线程
单Reactor多线程
多Reactor多线程

Proactor

异步IO思想实现的一种模式,所有IO操作都交给主线程和内核来处理,工作线程仅仅负责业务逻辑。
在Proactor中,用户函数启动一个异步的文件操作。同时将这个操作注册到多路复用器上。多路复用器并不关心文件是否可读或可写而是关心这个异步读操作是否完成。异步操作是操作系统完成,用户程序不需要关心。多路复用器等待直到有完成通知到来。当操作系统完成了读文件操作——将读到的数据复制到了用户先前提供的缓冲区之后,通知多路复用器相关操作已完成。多路复用器再调用相应的处理程序,处理数据。
参考

同步IO模拟Proactor

原理:主线程执行数据读写操作,区别于proactor是内核执行读写数据操作,读写完成之后,主线程通知工作线程通知这一完成事件,从工作线程的角度来看,它就直接获得了数据读写的结果,接下来只要对读写的结果进行逻辑处理就行了。

参考:两种高效的事件处理模式Reactor和Proactor
《Linux高性能服务器开发》

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值