一说起Leader/Followers并发模式,都会与Half-Async/Half-Sync并发模式进行比较,说LF模式更加高性能,成了一个高性能名词标签
符号,相反HA/HS仿佛成了一个低性能的名词标签,如果你的线程池不使用LF模式就谈论不上高效,要是你还在使用HA/HS模式,马上笼

统地建议换成LF模式,一切的问题会归根于HA/HS模式。那么为什么LF模式没有成一个标准的默认的并发模式呢,彻底取代其它并发模

式呢。因为Leader/Followers并发模式是设计用来解决Half-Async/Half-Sync并发模式在特定的使用场合中遇到的问题的。当使用

Half-Async/Half-Sync并发模式的变种Half-Reactive/Half-Sync的时,会伴随以下问题。
Half-Reactive/Half-Sync即,由一个线程进行Reactor(反应器)进行同步事件分离程序以及同步事件处理分派程序。事件处理程序可

以通过线程池共享队列,交给可以进行同步操作的线程进行。同步IO在Reactive线程中执行,事件后续处理交给Sync线程(s)。在Web服

务器,Reactive线程阻塞等待请求(数据接收)事件,并不阻塞地同步接收请求,将会因为流控而阻塞或大负载的文件输送操作移交到

Sync线程池的某一线程进行。
问题一:
这样的实现版本中就只有Reactive线程一个在进行同步I/O操作,虽然有多个句柄的同步指示事件通知不再阻塞,但却不能充分发挥多

线程将这些不再阻塞的句柄并发同步I/O操作。如果将同步I/O读取操作也移交Sync线程池的话,Reactive线程必须同步这些并发,等待

这些并发完成后再进行新一轮的同步事件分离程序等待。
问题二:
请求要输送到其它线程,所以必须使用堆复制请求。由于在多处理器环境中,线程的切换往往意味着处理器的切换,而切换处理器就会

有内存同质的问题,或者缓存(L1,L2 cache或MMU快表TLB)重新装载(即不亲和coherency一致)。简单地可以想像在内存寻址时,

CPU缓存缓存了内存页表及内存页表项,以便不用访问内存中的页表和页表项进行二次或多次内存访问。如果同步IO读出请求可以在同

一线程上处理,就可以尽量避免处理器的切换。但是这时又引入了另一个问题。要是所有线程都可以进行Reactor等待事件就好了。
问题三:
Reactor使用的同步事件分离程序,如select等往往是不可以对相同的句柄在多个线程进行阻塞等待的。如何能将同步事件通知不再阻

塞的句柄上的同步I/O并发掉,又可以保证只有一个线程使用Reactor进行同步事件分离程序等待,那么Leader/Followers模式就是最适

合且自然的选择了。
Leader/Followers并发模式是设计用来解决Reactor(反应器)在实际应用中使用线程池进行事件处理而伴随的问题。在基于IOCP的

Proactor(前摄器)应用多线程的场合,Leader/Followers并发模式就并不必要同时也不是最合适的选择,Ice的ThreadPool就是一个

实例,尽管在其文档上标榜其使了LF模式。

一次请求事件处理中包含了两步操作:同步不阻塞I/O读出请求以及处理请求。HA/HS模式,将上面两步归为异步不阻塞和同步,将一次

请求事件处理分别在两层服务的线程上执行。而LF模式是想方设法让一次请求事件处理执行在同一线程内。但是在Proactor事件模式中

,Proactor分离的是完成事件,随后的事件处理并不包含同步不阻塞I/O读出请求,而是直接对请求进行处理。并且IOCP可以被多个线

程进行事件分离等待,而IOCP本质是一个完成事件队列,事件处理的线程其实在共享一个队列,将完成事件同步处理,而系统相当于异

步服务层执行了我们发起的异步IO操作,并将完成异步IO操作的完成事件放入到IOCP的完成事件队列。Proactor模式可以视作HA/HS模

式的扩展,这时并不需要使用LF模式。而Half-Sync/Half-Reactiver的中层队列层就相当于一个I/O的完成事件队列,所以在基于IOCP

的Proactor上使用LF模式线程就不必要了,因为这里没有LF模式所要解决的问题。

Half-Async/Half-Sync并发模式是一种并发关系的模式,并不等同于多线程或线程池。系统的socket协议栈和我们在应用程序中使用的

socket同步操作接口,应用了这一并发模式。系统的协议栈在进行网卡的硬中断处理程序时,不可阻塞或长时间执行,必须高效地完成

以网卡缓存的数据交换和控制。这就相当于Half-Async层。系统离开系统调用前进行软中断处理程序将数据在协议栈向上传递到传输层

的缓存队列中,从而唤醒我们在应用发起的同步I/O操作。
Half-Async/Half-Sync并发模式应用在线程池设计时,就分为三个层,Half-Async不阻塞服务层,Half-Sync允许阻塞服务层,中间由

一层队列服务层进行交互。通常有一个线程池进行Half-Sync的服务。但并不是说Half-Async就只能一个线程进行服务,如果服务于

Half-Async层的线程不用进行同步并发的话,一样可以使用多个线程并发于Half-Async层,原则只有一个不可以阻塞。Half-

Reactive/Half-Sync模式的线程池中只有一个Reactive线程,是因为Reactor(反应器)使用同步事件分离程序不可以被多个线程对相

同的句柄进行等待。

其实epoll使用了类似Proactor模式,但是它发起的不是异步IO,而是异步的事件轮询。虽然epoll称自己是异步事件,但它的

epoll_wait事件分离程序却是句柄的同步事件。epoll利用句柄的等待队列,插入一个等候并绑定与poll不一样的处理程序,处理程序

将有事件通知的句柄入队到就绪队列。epoll(epoll_ctl而不是epoll_wait)发起的是异步的轮询,而就绪队列发生的是异步轮询的完

成事件,这个完成事件中包含了句柄的同步事件通知。epoll_ctl已经向句柄的发起了异步轮询,epoll_wait则是等待在就绪队列上分

离轮询完成的事件。为什么不干脆将事件处理程序挂在句柄的等待队列上,因为等待队列的处理程序运行在内核态,回调往往意味着颠

倒控制,在内核态回调用户态的代码,对于系统来说这是一件愚蠢的事情。

在《ACE程序员指南》一书中,作者为了突出LF模式比HA/HS模式的优越,给了一个HA/HS模式的实例。在ACE中,线程类继承ACE_Task可

以同时获得独立的消息(泵)队列服务。位于HA层为Manager线程类,维护着HS层的Worker线程类。HA层与HS层之间的队列服务层并不

由共享的队列方式实现,而是使用Worker线程类的独立消息(泵)队列来充当。这样的结果是,Worker线程类阻塞在各自的消息队列上

,事件处理必须经由HA层的Manager选出一个Worker并向它的消息队列发送消息。Worker线程被唤醒后处理事件,并在完成后入队到

Manager的空闲线程队列中。而Manager在它的消息队列上收到消息后,只是选出空闲Worker并转送消息。在他的这个模式实例中,每个

消息都必须唤醒Manager线程,再由Manager线程选出Worker线程并唤醒处理消息。即每次消息都唤醒两个线程,增加上下文切换来突出

LF模式的优越。同时Manager在选出Worker线程的执行,和Worker线程重新入队Manager的空闲队列又增加了线程同步操作。

ACE框架中有几个版本的Reactor,也只为基于select的Reactor提供了ThreadPool(LF模式)的版本ACE_TP_Reactor(,还有

Dev_Poll_Reactor,用于linux的epoll以及solaris的/dev/poll),而基于Windows系统的WaitForMutilpleObjects版本的

ACE_WFMO_Reactor,并没有提供一个LF线程池,因为WFMO可以在多个线程上同时对相同的内核对象进行事件等待,这是select所不能做

到的。另外ACE_Proactor也就没有提供LF线程池。ACE框架最终还是将线程池和线程池的并发模式的决定权交给了框架的使用者,除了

ACE_TP_Reactor,因为这是一个经典的案例,利用LF模式解决基于select的Reactor使用多线程事件处理时遇到的问题。

在Ice项目中,ThreadPool的Reactor版本实现了LF模式,线程池使用了Reactor进行事件分离。而在ACE项目中,由基于*nix的事件分离

程序的Reactor的事件处理循环实现LF并发模式,但并不提供线程池,多线程只需要运行Reactor的事件处理循环。这是不一样的出发点

的设计。

LF模式解决的问题的更多相关文章

  1. LF模式是个坑,ZeroIce中间件让你体会这个痛

    LF模式是个坑,一个小小的失误就可能使你的网络处理瘫痪,Ice就很好地展现了出来,换句话说,Ice中间件或是LF模式就是一个坑,如果你一不小心. LF模式的官方论文中,论述了此模式用于高性能网络并发模 ...

  2. 【Java EE 学习 19】【使用过滤器实现全站压缩】【使用ThreadLocal模式解决跨DAO事务回滚问题】

    一.使用过滤器实现全站压缩 1.目标:对网站的所有JSP页面进行页面压缩,减少用户流量的使用.但是对图片和视频不进行压缩,因为图片和视频的压缩率很小,而且处理所需要的服务器资源很大. 2.实现原理: ...

  3. spring通过工厂模式解决页面耦合问题

    spring通过工厂模式解决页面耦合问题

  4. 通过进入单用户模式解决linux中的rc.local修改后无法启动的问题

    问题:本想将teamviewer这个软件随linux自启动,所以将其启动命令放在rc.local中,但是重启后发现linux启动不起来了,系统前面都是正常启动的,就是无法进入帐户登陆界面,无法输入ro ...

  5. Centos7.6进入挂载硬盘后,进入应急模式(emergency mode)而非图形模式解决方法

    Centos7.6进入挂载硬盘后,进入应急模式(emergency mode)而非图形模式解决方法 话说某天我想在centos7.6中挂载个硬盘,结果刚在虚拟机中添加了一块硬盘,再次打开系统时,居然就 ...

  6. Hibernate:组合模式解决树的映射

    树经常用来展示目录结构,那么在Hibernate中怎样解决树的映射问题呢? 先来看一个分销商的树形结构的例子 所有分销商 东北区 辽宁省 沈阳医药 吉林省 华北区 北京市 北京医药 河北省 华南区 那 ...

  7. vi 替换命令“找不到模式”解决

    在linux vi编辑工具中使用替换命令操作时,会出现明明有匹配查找模式的数据.却报"找不到模式"问题. 原因是vi s///替换操作缺省针对行,若要生效,则须要将光标移动到指定行 ...

  8. 用工厂模式解决ASP.NET Core中依赖注入的一个烦恼

    这是最近在实际开发中遇到的一个问题,用 asp.net core 开发一个后端 web api ,根据指定的 key 清除 2 台 memcached 服务器上的缓存.背景是我们在进行 .net co ...

  9. TFTP 1.68智能刷机全能版发布,TTL线在CFE模式解决BCM5357如斐讯FIR302B等产品变砖问题

    TFTP 智能刷机从发布以来一直受广大刷机朋友的喜爱,也有很多人一直加我的Q问如何刷机? 在这里我要告诉大家一下,由于机型种类繁多,建议有遇到问题,直接百度,有空的时候我能回答我尽量回答,其他的爱莫能 ...

随机推荐

  1. Mybaits 源码解析 (一)----- 搭建一个mybatis框架(MyBatis HelloWorld)

    源码分析之前先搭一个mybatis的demo,这个在看源码的时候能起到了很大的作用,因为在看源码的时候,会恍然大悟,为什么要这么配置,为什么要这么写.(老鸟可以跳过这篇) 开发环境的准备 创建mave ...

  2. ESP8266开发之旅 网络篇⑥ ESP8266WiFiGeneric——基础库

    1. 前言     在前面的博文中,博主介绍到ESP8266WiFi库是包含了很多功能的一个超级库.ESP8266WiFi库不仅仅局限于 ESP8266WiFi.h 和 ESP8266WiFi.cpp ...

  3. java ThreadLocal线程设置私有变量底层源码分析

    前面也听说了ThreadLocal来实现高并发,以前都是用锁来实现,看了挺多资料的,发现其实还是区别挺大的(感觉严格来说ThreadLocal并不算高并发的解决方案),现在总结一下吧. 高并发中会出现 ...

  4. vue表单和组件使用

    表单: <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title ...

  5. 【Spring Boot】java.lang.NoSuchMethodError: org.springframework.web.util.UrlPathHelper.getLookupPathForRequest(Ljavax/servlet/http/HttpServletRequest;Ljava/lang/String;)Ljava/lang/String;

    Digest:今天Spring Boot 应用启动成功,访问接口出现如下错误,不知到导致问题关键所在,记录一下这个问题. 浏览器报500错误 项目代码如下 Controller.java packag ...

  6. 为啥不能#define private public了?

    今天在写一个单元测试的时候出现了如下编译错误: 以前用gtest为了测试业务代码里的private函数和变量,一直是在单元测试代码通过#define private public这样的trick达到测 ...

  7. 医生智能提醒小程序数据库设计心得——Legends Never Die

    数据库设计心得 根据我们小组数据库设计的整个流程,我们将整个数据库设计划分为两个具体的阶段,在每个阶段需要进行不同的准备,有不同的注意事项,接下来我们将结合在数据库设计过程中遇到的一些问题和困难,提出 ...

  8. 【建站02】WordPress主题设置

    大家好,我是帝哥.相信很多朋友看了我上一篇文章的介绍之后已经可以搭建自己的个人网站了,但是网站的功能和美观程度都还是有所欠缺的,现在呢,再给大家大概的介绍一些如何美化自己的网站,当然了,这个过程也是很 ...

  9. NOIP模拟 31

    补坑 skyh又AK 赛时榜搜索我的姓: 下一条 ... 自闭了. (只是表达对B哥强烈的崇敬) (如果B哥介意我把名字贴出来请联系我删掉) T1一打眼,好像就一个gcd 康了眼大样例,觉得没啥问题 ...

  10. 史上最全的excel读写技术分享

    目录 简介 导出excel常用的几种方法 POI CSV jxl jxls easyexcel 快速入门 代码解读 总结 常用API 单元格样式 合并单元格 数据样式 多sheet设置 单元格添加超链 ...