• 2.线程模型概述


    目前存在的线程模型有:

    • 传统阻塞 IO 服务模型
    • Reactor 模式, 根据 Reactor 数量和处理资源池线程的数量不同, 又有 3 重典型的实现.
    • 单 Reactor 单线程
    • 单 Reactor 多线程
    • 主从 Reactor 多线程.

    传统阻塞 IO 服务模型

    1.一个线程对应一个客户端, 如果客户端过多就会占用很大的系统资源.
    2.没有可读数据时, 线程会阻塞, 造成资源浪费.

    Reactor 模式

    下图只是对 Reactor 模式的一个整体理念, 当涉及到三个具体实现时, 有不同的变化.

    基于 I/O 复用模型: 多个连接共用一个阻塞对象, 应用程序只需要在一个阻塞对象等待, 无需阻塞等待所有连接. 当某个连接有新的数据可以处理时, 操作系统通知应用程序, 线程从阻塞状态返回, 开始业务处理.

    基于线程池复用线程资源: 不必再为每个连接创建线程, 将连接完成后的业务处理任务分配给线程进行处理, 一个线程可以处理多个连接的业务.

    就是说, 服务处理器使用 I/O 复用监听一个或多个客户端的输入事件, 然后将这些事件分发到不同的线程处理.

    也可以简单粗暴的理解为: IO多路复用 + 线程池 = Reactor 模式.

    单 Reactor 单线程

    1.Reactor 对象通过 Select 监控客户端请求事件, 收到事件后通过 Dispatch 进行分发;
    2.如果是建立连接请求事件, 则由 Acceptor 通过 Accept 处理连接请求, 然后创建一个 Handler 对象处理连接完成后的后续业务处理;
    3.如果不是建立连接事件, 则 Reactor 会分发调用连接对应的 Handler 来响应;
    4.Handler 会完成 Read→业务处理→Send 的完整业务流程.

    优点: 模型简单, 没有多线程、进程通信、竞争的问题, 全部都在一个线程中完成.

    缺点: 性能问题, 只有一个线程, 无法完全发挥多核 CPU 的性能. Handler 在处理某个连接上的业务时, 整个进程无法处理其他连接事件, 很容易导致性能瓶颈.

    可靠性问题, 线程意外跑飞, 或者进入死循环, 会导致整个系统通信模块不可用, 不能接收和处理外部消息, 造成节点故障.

    使用场景: 客户端的数量有限, 业务处理非常快速, 比如 Redis, 业务处理的时间复杂度 O(1).

    单 Reactor 多线程

    1.Reactor 对象通过 Select 监控客户端请求事件, 收到事件后通过 Dispatch 进行分发.
    2.如果是建立连接请求事件, 则由 Acceptor 通过 Accept 处理连接请求, 然后创建一个 Handler 对象处理连接完成后续的各种事件.
    3.如果不是建立连接事件, 则 Reactor 会分发调用连接对应的 Handler 来响应.
    4.Handler 只负责响应事件, 不做具体业务处理, 通过 Read 读取数据后, 会分发给后面的 Worker 线程池进行业务处理.
    5.Worker 线程池会分配独立的线程完成真正的业务处理, 如何将响应结果发给 Handler 进行处理.
    6.Handler 收到响应结果后通过 Send 将响应结果返回给 Client.

    优点: 可以充分利用多核 CPU 的处理能力.

    缺点: 多线程数据共享和访问比较复杂; Reactor 承担所有事件的监听和响应, 在单线程中运行, 高并发场景下容易成为性能瓶颈.

    主从 Reactor 多线程

    这种模式是对单 Reactor 的改进, 由原来单 Reactor 改成了 Reactor 主线程与 Reactor 子线程.

    1.Reactor 主线程的 MainReactor 对象通过 select 监听连接事件, 收到事件后, 通过 Acceptor 处理连接事件.
    2.当 Acceptor 处理完连接事件之后, MainReactor 将连接分配给 SubReactor.
    3.SubReactor 将连接加入到连接队列进行监听, 并创建 handler 进行事件处理.
    4.当有新的事件发生时, SubReactor 就会调用对应的 handler 处理.
    5.handler 通过 read 读取数据, 交由 Worker 线程池处理业务.
    6.Worker 线程池分配线程处理完数据后, 将结果返回给 handler.
    7.handler 收到返回的数据后, 通过 send 将结果返回给客户端.

    MainReactor 可以对应多个 SubReactor.

    这种优点多多,各个模块各司其职,缺点就是实现复杂.

    参考资料

    网络编程中的线程模型

    30-07 之應用層的 I/O 優化 - 非阻塞 I/O 模型 Reactor

    深入了解Netty【五】线程模型

  • 相关阅读:
    原创frame-relay配置
    iptables详解和练习
    nfs-rpcbind-portmap挂载nfs-network file system
    linux-user-group添加与删除
    cgi-fastcgi-fpm
    lamp介绍
    子签CA以及给别人发CA
    正则表达式
    字符集和字符编码
    C++11新特性
  • 原文地址:https://www.cnblogs.com/scikstack/p/13523140.html
Copyright © 2020-2023  润新知