半同步/半异步模式,半同步半反应堆reactor模式

  • Post author:
  • Post category:其他


前言

看游双的书并理解,个人学习,有错麻烦提一下,感谢

事件处理模式和并发模型的区别

这篇要介绍的事件处理模式有reactor和proactor;而要介绍的并发模型有半同步/反应堆和半同步半异步

事件处理模式,指的是…TODO

事件处理模式

事件处理模式,本文介绍的有两种,是reactor(反应堆)和proactor模式,(还有没有其他的呢?)

同步IO模型用于实现reactor模式,异步IO模型用于实现proactor模式

异步IO比如有POSIX的 AIO和linux下原生的libaio, 同步IO的例子则是我们平常使用的read和write(见参考资料[2])

同步IO比如我们用的read,调用后让操作系统把数据从内核缓冲区搬到用户态中read的参数中,这里是从调用到read返回要等数据出来,

而异步IO,在参考资料[2]中提到select和poll也可以作为异步IO一部分,这些工作在调用异步IO的注册函数后,内核自己把数据拉取出来后,select或者poll返回通知用户,这期间不占用用户的CPU;拉取数据过程不占用CPU时间,当select或poll返回后直接就有了用户态的数据,而不需要再自己拉取回来(参考资料[3]),可以看出优点是省时,但是缺点是,由上述可知,编程起来比同步IO更复杂

从上面的描述可以看出,同步IO是阻塞IO,异步IO是非阻塞IO

reactor

reactor模式的定义,在游双的书中是这么说的:IO线程(主线程)只监听事件(如epoll_wait)和有事件则通知工作线程,而工作线程负责除此之外所有工作,入读写数据(read,write),接受连接(accept),处理请求(处理发来的数据等)

参考资料6提到是种编程模有以下三种角色:


Reactor

将I/O事件分派给对应的Handler;

Acceptor

处理客户端新连接,并分派请求到处理器链中;

Handlers

执行非阻塞读/写 任务

proactor

proactor模式是利用了异步IO,好处是在游双的书里是这么说的:proactor模式把IO操作都给了内核处理(说的应该是主线程调用异步读写的API,内核完成读写),同时这个也是proactor的一大好处,只让工作线程实现业务逻辑,解耦了其他部分

内核完成后直接通知工作线程(应该也可以让内核完成后通知主线程,主线程通知工作线程吧),工作线程只负责业务逻辑,也就是上面reactor说的处理请求(处理数据),(accept谁来做呢?)

模拟proactor模式

因为linux对异步IO的支持不是很完美,故一般用同步IO来模拟proactor模式,前面说了因为proactor模式能让工作线程只解决业务逻辑,这里模拟的proactor模式也是.把IO任务(read,write)交给主线程做,完成后再把数据交给工作线程,详细步骤见游双的书

并发模式

并发模式是并发的编程模式,和前面讲的事件有相似之处(实际并发模式和事件处理模式的用词我还不是很懂),异步IO的读写交给内核,而这里并发模式的耗时任务也是交给信号处理函数,来做,完成后再通知原本的线程

这里讲的例子都是服务器编程的例子,而服务器编程要关注的都是三个半事件中的其中,这里游双书里所谓的并发模式也是专注于服务器编程的吧

全异步模式和全同步模式

这个不在游双的书里,来自面经,全同步是多线程,每个线程进行阻塞IO监听,IO事件发生后再执行动作,即全同步,可参照参考资料[5]iterator模型,可以是多线程多进程

全异步,游双上面给出的半同步半异步例子我感觉实际上是全异步模型…

半同步半异步模式

根据同步和异步的性质,在这个半同步半异步模式中,同步线程用于处理客户逻辑,而异步线程用于处理IO事件,为什么呢?因为IO不消耗CPU,这些干等的操作可以由内核接管,而客户逻辑(处理数据)需要CPU处理

这里说的异步线程处理IO,同步线程处理客户数据,两个线程之间的交互是客户数据(这不是proactor模式吗,难以分清区别TODO)

这里异步线程完成了IO操作后,如何选择同步线程即工作线程的方法有几种,第一种是工作线程通过抢占锁,一种是通过条件变量condition.notify_one操作,或者是Round robin方式(可以找代码看看),还有信号量(这个怎么做呢?)

代码:在游双的书里15章给出了例子

变体:半同步/半反应堆模式

游双说是半同步半异步的变体,我看着的区别是主线程和工作线程之间的任务分配方式不同,这种模式是IO线程向工作线程分配的内容是connection fd,并且分配方式是通过锁的抢占.

这里为什么说是半反应堆模式呢,因为用到了reactor模式,哪里用到了呢,IO线程只监听连接到来事件,而工作线程要执行读写.

游双的书里还提到,半同步/半反应堆模式可以用模拟proactor模式来完成(那为什么不说半同步半proactor模式..),即让IO线程完成读写,IO线程向工作线程分发的是已接受的数据

是变种还是一个新模型?半同步/半异步模式

这里每个工作线程和IO线程都用了epoll_wait来异步读,作者又说道它实际不是严格的半同步半异步

领导者追随者模式

这个面试不是重点?略

后记

是我理解有误吧..这半同步/半异步,半同步/半reactor模式看的我云里雾里的,这不是明显的reactor模式+线程池的实现吗…为什么游双书里要这么分法..却给出这种例子..

半同步半异步不是多reacor的实现变种吗..并发不如去看参考资料[5]..半同步半反应堆就是one reactor+threadpool吧,这里的半同步半异步例子就是主从reactor而没有threadpool的吧..

参考资料

  1. [1](

    https://blog.csdn.net/naipeng/article/details/89918482

    )
  2. [2]

    https://www.cnblogs.com/skyofbitbit/p/3654531.html
  3. [3]C++教程网,大并发服务器开发(实战)
  4. [4]游双的书
  5. [5](

    https://blog.csdn.net/ptgood/article/details/106747851

    )

  6. https://blog.csdn.net/bingxuesiyang/article/details/89888664



版权声明:本文为ptgood原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。