zoukankan      html  css  js  c++  java
  • Reactor 模型(一)基本并发编程模型

    Reactor 模型(一)基本并发编程模型

    在讲解 Reactor 线程模型之前,我们需要先对基本并发编程模型:串行工作模型、并发工作模型进行讲解。

    串行工作者模型和并行工作者模型关注的是将任务划分为 2 个阶段:一是任务的接受阶段;二是任务的处理阶段。而 Reactor 线程模型关注的是上述第二个阶段:任务在处理的过程中,继续划分为多个步骤进行处理。

    一、串行模型

    我们以一个典型的任务处理流程,来说明为什么要将任务的接受流程与处理流程划分开来

    并发操作

    在这个例子中,一个 Worker 线程来处理用户提交的任务,任务的处理步骤粗略的分为:接受任务和处理任务两个阶段。当Worker接受到一个任务之后,就立刻进行处理,也就是说任务接受和任务处理是在同一个 Worker 线程中进行的,没有进行区分。这样做存在一个很大的问题是,必须要等待某个 Task 处理完成之后,才能接受处理下一个 Task。

    而通常情况下,任务的处理过程会比任务的接受流程慢得多。例如在处理任务的时候,我们可能会需要访问远程数据库,这属于一种网络 IO。通常情况下 IO 操作是比较耗时的,这直接影响了下一个任务的接受,而且通常在 IO 操作的时候,CPU 是比较空闲的,白白浪费了资源。

    因此我们可以考虑将任务的接受与处理分为两个线程进行处理,一个只负责接受任务,一个只负责处理任务。

    这就演化出了第一个线程模型:串行工作者模型。如下所示:

    串行模型

    在这种情况下,接受任务的线程称之为 Accept Thread,其将接受到的任务放到一个任务队列中,因此能立即返回接受下一个任务。而 Worker 线程不断的从这个队列中取出任务进行异步执行。

    目前这种情况存在一个很大的问题,在于任务处理的太慢,导致队列里积压的任务数量越来愈大,任务不能得到及时的执行。所以我们可以用多个 Worker Thread 来处理任务。这就是串行工作者模型的并发版本-并行工作者模型。

    二、并行模型

    在并行工作者模型中,有一个 Accpet Thread,多个 Worker Thread,因为 Worker Thread 的功能都相同,所以我们通常会将其划分到一个组中(Worker Thread Group)。

    在具体实现上,并行工作者线程模型有两种设计方式,以下分别进行介绍。

    2.1 基于公共任务队列

    并行工作者线程模型设计方式一:基于公共任务队列

    accept Thread 将接受到的任务放到任务队列中,Worker Thread group 中的多个 Worker Thread 并行的从公共的队列中拉取任务进行处理。

    并行模型-公共任务队列

    熟悉java线程池 的用户可能已经发现,可以用ThreadPoolExecutor 来实现右半部分的功能,因为ThreadPoolExecutor 就是多个线程从一个公共的任务队列中拉取任务进行执行。通过在main线程中接受任务,将任务提交到线程池中,即可以完成上述线程模型。

    2.2 每个 Worker Thread 维护自己的任务队列

    在第一种方式中,由于多个Worker线程同时从一个公共的任务队列中拉取任务进行处理,因此必须要进行加锁,因而影响了效率。因此又有了下面一种设计方式:Reactor Thread直接将任务转发给各个 Worker Thread,每个 Worker Thread 内部维护一个队列来处理,如下图

    并行模型-私有任务队列

    这种方式的设计,避免的锁竞争,因为每个 Worker Thread 都从各自的队列中取出任务进行执行。实际上,Netty 的实现中,就是为每个 Worker Thread 维护了一个队列。

    需要注意的是:由于现在是 Accpet Thread 直接给过个 Worker Thread 转发任务,任务分配的平均的责任就落到了 Reactor Thread 的身上。


    每天用心记录一点点。内容也许不重要,但习惯很重要!

  • 相关阅读:
    如何完全禁用或卸载Windows 10中的OneDrive
    ASP.NET Web API从注释生成帮助文档
    c#中使用easyUI的DataGrid组件
    第三方分页控件aspnetPager出现问题解决方法
    ActionResult派生类
    Razor引擎的转换数据类型
    ViewData与ViewBag比较
    .net开源后可以查看的源代码
    如何让一个类可以被foreach枚举?
    .NET Framework中Object基类有哪些方法?
  • 原文地址:https://www.cnblogs.com/binarylei/p/10024302.html
Copyright © 2011-2022 走看看