文档章节

服务器高并发设计模式

满小茂
 满小茂
发布于 2016/04/13 23:17
字数 1670
阅读 212
收藏 3

半同步/半异步模式

先解释一下同步和异步的区别,与刚才I/O的同步、异步不一样,在并发模式中,这里的“同步"指的是程序完全按照代码的顺序执行,“异步”指的是程序的执行需要由系统事件来驱动,比如说信号、中断等。下图就清楚的解释了同步和异步操作的过程:

两种高效的事件处理模式和并发模式
 

这样看来,显然异步线程的执行效率高,但是它的编写相对复杂,难于调试,然而同步线程刚好相反,逻辑简单,但效率较差。半同步/半异步模式就结合了同步线程与异步线程的优点,它在处理I/O事件时使用异步线程,处理客户逻辑则使用同步线程。这样既满足了客户连接的实时性,又能同时处理多个连接。那么它是如何同将同步与异步结合起来的?实现半同步/半异步模式需要三个模块:异步处理模块、同步处理模块和队列模块

举个例子:

"一家律师事务所有一个前台接待员,每一位想寻找律师的客户,都会先由接待员接待,接待员会给每位顾客都安排一个律师来处理客户的案件,(假设一个律师在同一时间只能处理一个客户的案子)接待员只有一个人,但他可以接待所有客户,不过它也只负责接待,哪怕你的案件再复杂,都是律师的事儿,跟接待员没关系,而分配的依据可以是预约情况或者案件类型。"

在上面这个例子中,那个前台接待员就是异步处理模块,他一个人要处理多个I/O请求(客户),律师则是同步处理模块,每一个律师分别对应一个客户,根据客户的不同需求作出处理,而要让异步模块与同步模块连接起来,就需要插入一个队列模块,它将接待完毕的客户排一个队,等那个律师有时间的时候就来这个队列里领走一个客户处理,当然,队列怎么排,分为几个队列,就看客户到达的时间或者需求来决定了。

 

在实际使用中,我们一般使用多路复用IO在主线程上监听客户端的连接,监听到新的客户请求后,就将其封装成请求对象,然后插入请求队列中,同时,有许多工作线程可以来读取并处理该请求对象,具体选择哪个工作线程来为新的客户进行处理,取决于请求队列的设计。在这个模式中,最可能被阻塞的操作放在同步模块中,这样不会影响到异步模块的处理,不同模块可以使用不同的同步策略,互不干扰,模块间通信则使用ipc实现,但这样也造成了在同步模块和异步模块之间使用队列模块传送数据的时候,由于数据拷贝和上下文切换导致的性能消耗。

 

 

 

半同步/半反应堆模式

        半同步/半反应堆模式其实是半同步/半异步模式的一种变体,其中异步线程只有一个,由主线程充当,如果有连接到来或事件发生,主线程就将该socket插入请求队列中,直到这里与半同步/半异步模式都是一样的,但是在半同步/半反应堆模式中,当有任务到来时,选择哪个工作线程不是由算法或时间设置好的,而是由所有的工作线程竞争来的,它们通过竞争(比如申请互斥锁)来获得任务的接管权,这样的竞争机制使得当前只有空闲的工作线程才能来竞争,自然的形成了资源平衡。

 

          上图中主线程插入的请求队列是就绪的连接socket,这说明图示的半同步/半反应堆模式采用的事件处理模式是Reactor模式。半同步/半反应堆模式也可以采用模拟Proactor的事件处理模式,也就是由主线程完成数据的读写。主线程一般会将应用程序数据与其他信息一起封装为一个任务对象,然后将其插入请求队列。工作线程可以直接处理,不用读写。 半同步/半反应堆模式因为也是主线程和工作线程共享任务队列,所以也会存在与半同步/半异步模式一样的问题,就是每次堆队列进行操作,都需要进行加锁,从而消耗cpu的时间。而且一个线程同一时间只能处理一个客户请求,如果队列中积累了很多任务,增加工作线程的话,工作线程的切换也会耗费大量cpu时间,这种问题有一种相对高效的解决方式:即在每个工作线程上也使用epoll_wait,这样每个工作线程都能处理多个客户连接了。

 

 

领导者/追随者模式

           领导者/追随者模式是指多个工作线程轮流监听、分发、处理事件的一种模式。在任意事件,程序都仅有一个领导者线程,它负责监听I/O事件。其他线程都是追随者,它们休眠在线程池中等待成为新的领导者。当领导者线程检测到I/O事件时,首先要从线程池中选出新的领导者线程,然后处理I/O事件。此时,新的领导者线程等待新的I/O事件,旧的领导者线程处理I/O事件,实现并发。

           领导者/追随者模式最大的优点在于,它是自己监听I/O事件并处理客户请求,也就是说从接收到处理都是在同一线程中完成,所以不需要在线程之间传递任何额外的数据,也不用在线程间同步对请求队列的访问。但是它也有明显的缺点,就是只支持一种事件源集合,所以导致它不能像上述那样让每个线程独立的管理多个客户连接。

 

© 著作权归作者所有

共有 人打赏支持
满小茂
粉丝 68
博文 119
码字总数 131754
作品 0
成都
程序员
1、单例模式

定义: 单例模式是一种常用的软件设计模式。在它的核心结构中只包含一个被称为单例的特殊类。通过单例模式可以保证系统中一个类只有一个实例。即一个类只有一个对象实例。 特点: 1、单例类只...

晚天吹凉风
02/22
0
0
设计模式(创建型)之单例模式(Singleton Pattern)

转载来自:http://blog.csdn.net/yanbober/article/details/45312675 PS一句:最终还是选择CSDN来整理发表这几年的知识点,该文章平行迁移到CSDN。因为CSDN也支持MarkDown语法了,牛逼啊! 【...

xiaopangzi520
06/26
0
0
编程中的那些经典套路——设计模式汇总

在正式阅读前,我先谈谈我们该用什么姿势和心态学习设计模式: 如果你还没有过多的编程经验(泛指半年以下),我建议你把它当做小说来看,能看懂多少是多少,因为半年以下经验的程序员用到设...

gzchen
08/27
0
0
设计模式学习笔记之-代理模式

代理模式中,客户不会直接调用目标对象而是通过一个代码对象,客户调用代理对象代理对象去调用目标对象,起到对象与对象间的隔离作用。有时候我么不想直接访问目标对象,有时候我们不能直接访...

申文波
03/05
0
0
编程中的那些套路——关于策略模式

该文章属于《编程中的那些经典套路——设计模式汇总》系列,并且以下内容基于语言PHP 今天讲讲策略模式,策略模式 和工厂模式十分相像(或者说在代码逻辑层面,他们是一样的)。 但策略模式与...

gzchen
08/27
0
0

没有更多内容

加载失败,请刷新页面

加载更多

20180920 rzsz传输文件、用户和用户组相关配置文件与管理

利用rz、sz实现Linux与Windows互传文件 [root@centos01 ~]# yum install -y lrzsz # 安装工具sz test.txt # 弹出对话框,传递到选择的路径下rz # 回车后,会从对话框中选择对应的文件传递...

野雪球
今天
2
0
OSChina 周四乱弹 —— 毒蛇当辣条

Osc乱弹歌单(2018)请戳(这里) 【今日歌曲】 @ 达尔文:分享花澤香菜/前野智昭/小野大輔/井上喜久子的单曲《ミッション! 健?康?第?イチ》 《ミッション! 健?康?第?イチ》- 花澤香菜/前野智...

小小编辑
今天
7
3
java -jar运行内存设置

java -Xms64m #JVM启动时的初始堆大小 -Xmx128m #最大堆大小 -Xmn64m #年轻代的大小,其余的空间是老年代 -XX:MaxMetaspaceSize=128m # -XX:CompressedClassSpaceSize=6...

李玉长
今天
4
0
Spring | 手把手教你SSM最优雅的整合方式

HEY 本节主要内容为:基于Spring从0到1搭建一个web工程,适合初学者,Java初级开发者。欢迎与我交流。 MODULE 新建一个Maven工程。 不论你是什么工具,选这个就可以了,然后next,直至finis...

冯文议
今天
2
0
RxJS的另外四种实现方式(四)——性能最高的库(续)

接上一篇RxJS的另外四种实现方式(三)——性能最高的库 上一篇文章我展示了这个最高性能库的实现方法。下面我介绍一下这个性能提升的秘密。 首先,为了弄清楚Most库究竟为何如此快,我必须借...

一个灰
今天
3
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部