前言

  上一篇文章《后端服务器网络编程之 IO 模型》中讲到服务器端高性能网络编程的核心在于架构,而架构的核心在于进程/线程模型的选择。本文将主要介绍传统的和目前流行的进程/线程模型,在讲进程/线程模型之前需要先介绍一种设计模式: Reactor 模式,不明白的看这里《Reactor 模式详解》,文中有一句话对 Reactor 模式总结的很好,引用下。

对Reactor 模式还不了解的朋友可以看看这个视频讲解:详解网络编程相关的细节处理丨 reactor模型

Reactor 模式首先是事件驱动的,有一个或多个并发输入源,有一个Service Handler,有多个Request Handlers;这个Service Handler会同步的将输入的请求(Event)多路复用的分发给相应的Request Handler。如果用图表示的如下:

  不知道读者有没有发现 Reactor 模式跟 IO 模型中的 IO 多路复用模型非常相似 ,在学习网络编程过程中也被这两个概念迷惑了很久。其实在设计模式层面 IO 多路复用也是采用 Reactor 模式的。IO 多路复用模型可以看成是 Reactor 模式在 IO 模型上的应用,而今天我们要讲的是 Reactor 模式在进程/线程模型上的应用。

  在我的看来,进程/线程模型可以分为非 Reactor 模式和 Reactor 模式两种(当然还有 Proactor 模式,这种本文先不讲,因为使用的比较少,而且我也还没搞懂这种模式)。非 Reactor 模式和 Reactor 模式的两种进程/线程模型下具体又分很多种,后面会一一列举。非 Reactor 模式的进程/线程模型是传统的模型,现在已经很少见,放在这里主要是让读者做个了解同时与 Reactor 模式的进程/线程模式做个对比。

非 Reactor 模式的进程/线程模型

  传统模型不使用 IO 多路使用,所以问题比较多。初学者建议看下这部分,如果你觉得被迷糊了或者不感兴趣可以跳过该部分,直接看 Reactor 模式的部分即可。但该部分的第 1、2 点需要了解下。

1、单进程单线程

  描述:这种模型所有的逻辑都在在一个进程中,包括建立连接->Read 连接上的数据->业务处理->Write 回一些数据然后一直循环下去。该模型一次只能处理一个连接,这个在真正的应用中是没有的。初学者在模仿《Unix网络编程卷 I》例子编写网络程序时应该会使用这种模型,当然例子中一般会在 Write 后面多个 Close 连接的动作,以免在处理下一个连接的时候造成前一个句柄泄露。

  优点:代码简单,无需去了解进程、线程的概念,适合学习网络编程的初学者。在不了解进程/线程模型情况下的默认模型。

  缺点:没有任何实用价值。

2、单进程多线程

  描述:进程只做建立连接的动作,每接收一个连接就创建一个线程,在此连接上的读->业务处理->写->关闭连接都在线程中去做,可以采用线程池的方式减少线程的创建和销毁。这种线程模型有一定的应用场景,Tomcat 三种线程模型之 BIO 用的就是这种进程/线程模型。初学者在学习完单进程单线程模型后对线程有所了解即可开始学习该种模型,可以实现一个简单的聊天室程序。

  优点:可以同时与多个 Client 建立连接,接收连接和处理连接业务分开。

  缺点:每个连接占用一个线程,当连接上没有数据的时候造成线程资源浪费,可以建立的连接数比较有限。

分享更多关于 Linux后端开发网络底层原理知识学习提升 点击 学习资料 获取,完善技术栈,内容知识点包括Linux,Nginx,ZeroMQ,MySQL,Redis,线程池,MongoDB,ZK,Linux内核,CDN,P2P,epoll,Docker,TCP/IP,协程,DPDK等等。

完整视频链接点击:C/C++Linux服务器开发/Linux后端架构师-学习视频

3、多进程单线程

  描述:

  (1) 主进程启动时创建监听套接字并监听,然后 fork 出 N 个子进程。

  (2) 由于父子进程的继承性,子进程同时也在端口监听,然后在父进程中关闭监听。

  (3) 父进程负责子进程的创建、销毁、资源回收等,子进程负责连接的建立->Read->业务处理->Write 等。

  由于所有进程都在同一个端口监听,该模型会出现一个比较知名的现象---惊群现象:当有一个连接来临时,所有子进程都会被唤醒,但是最后能与 Client 建立连接的只有一个,造成资源浪费(系统调度也是消耗 CPU 的)。不过 linux 2.6 版本以后已经在内核消除了惊群,当有连接来临只会唤醒一个等待在 accept() 上的进程。即使内核没修复,在应用层也可以用锁的方式防止惊群。

  缺点:这种模型是单进程单线程的进化版本,然而并没有什么卵用。且增加了开发的难度。所以不列出它的优点,介绍这种模型主要是引出惊群的概念,在后面的 Reactor 模型中的多进程情况下也会出现类似的情况。

Reactor 模式的进程/线程模型

  该模式一般是 Reactor 模型 + IO 多路复用,下面的任何一种模型都具有一定的实用场景。

1、单进程单线程

  描述:只有一个进程,监听套接字和连接套接字上的事件都由 Select 来处理,

  (1) 如果有建立连接的请求过来,Acceptor 负责接受并与之建立连接,同时将连接套接字加入 Select 进行监听;

  (2) 如果某个连接上有读事件则进行 Read->业务处理->Write 等操作;

  (3) 如此循环反复。

  优点:编程简单,对于业务处理不复杂的后台,基本能满足服务器端网络编程。老东家的服务器端程序全是这种模式,主要原因有如下

  (1) 如果一台机器性能不行,那就向集群中新增一台。

  (2) 业务处理并不复杂。

  (3) 扩展成多进程的话,如果不是多核意义不大。

  (4) 如果采用单进程多线程,C++ 处理线程不像 Java 简单,还要考虑并发的问题,收益比不大。

  缺点:会有阻塞,在进行业务处理的时候不能进行其他操作:如建立连接,读取其他套接字上的数据等。

2、单进程多线程

  描述:与单进程单线程类似,不同的是该模型将业务处理放在线程中,进程就不会阻塞在业务处理上。

  优点:比较完美的进程/线程模型,在 Java 实现中复杂度也不高。很多网络库都是基于此,比如 Netty 。

  缺点:待补充。

3、多进程单线程:

  描述:与非 Reactor 模式中的多进程单线程相似,只是本模式在子进程中使用了 IO 多路复用,实用性以下就上来了。大名鼎鼎的 nginx 就采用这种进程/线程模型

  优点:编程相对简单,充分利用多核。能满足高并发,不然 nginx 也不可能采用这种模式。

  缺点:子进程还是会阻塞在业务处理上。

分享更多关于 Linux后端开发网络底层原理知识学习提升 ,完善技术栈,内容知识点包括Linux,Nginx,ZeroMQ,MySQL,Redis,线程池,MongoDB,ZK,Linux内核,CDN,P2P,epoll,Docker,TCP/IP,协程,DPDK等等。

完整视频链接点击:C/C++Linux服务器开发/Linux后端架构师-学习视频

4、多进程多线程

  描述:这里不再画出图形,就是在在子进程上将业务处理交给多线程处理,参考单进程多线程里的线程池那里。

  优点:充分利用多核同时子进程不会阻塞在业务处理上

  缺点:编程复杂。

5、主从进程 +多线程:

  描述:前面几种 Reactor 模式的进程/线程模型中,连接的建立和连接的读写都是在同一进程中。本模型中将连接的建立和连接读写放在不同的进程中。

  (1) 主进程在监听套接字上 Select 阻塞,一旦有请求过来则与之建立连接,并将连接套接字传递给从进程。

  (2) 从进程在连接套接字上 Select 阻塞,一旦连接上有数据过来则进行 Read,并将业务处理通过线程来处理。如果有必要还会向连接 Write 数据。

  优点:连接的建立和连接的读写分开在不同进程中,处理效率会更高。该模型比单进程多线程模式还更优一点,且也可以利用多核。

Linux后端服务器网络编程之线程模型丨reactor模型详解相关推荐

  1. Linux 高性能服务器网络编程(一)

    Linux 高性能服务器网络编程 Linux网络编程基础API Socket 地址API 通用socket 地址 专用Sokect地址 IP地址转换函数 创建socket(socket) 命名(绑定) ...

  2. 网络编程中的SO_REUSEADDR和SO_REUSEPORT参数详解

    1.SO_REUSEADDR: 在BSD中,SO_REUSEADDR选项有两个用户: 如果有socket绑定了0.0.0.0:port:设置该参数后,其他socket可以绑定本机ip:port.(该功 ...

  3. linux服务器网络编程之线程模型

    前言   本文将主要介绍传统的和目前流行的进程/线程模型,在讲进程/线程模型之前需要先介绍一种设计模式: Reactor 模式.Reactor 模式首先是事件驱动的,有一个或多个并发输入源,有一个Se ...

  4. 手把手叫你玩转网络编程系列之三 完成端口(Completion Port)详解

    2019独角兽企业重金招聘Python工程师标准>>> 前 言 本系列里完成端口的代码在两年前就已经写好了,但是由于许久没有写东西了,不知该如何提笔,所以这篇文档总是在酝酿之中--酝 ...

  5. 【Java网络编程与IO流】Http协议详解以及面试有关问题

    HTTP协议详解以及面试有关题目 1 HTTP请求 一个HTTP请求报文由请求行.请求头部.空行和请求数据四个部分组成. 1.1 请求行 请求行中有请求方法字段.URL字段和HTTP协议版本3个字段组 ...

  6. Linux 网络编程学习笔记——三、TCP 协议详解

    目录 一.TCP 服务的特点 传输层协议主要有 TCP 协议和 UDP 协议,前者相对于后者的特点是:面向连接.字节流和可靠传输. 使用 TCP 协议通信的双方必须先建立连接,然后才能开始数据的读写. ...

  7. Linux 网络编程学习笔记——二、IP 协议详解

    目录 一.IP 服务的特点 IP 协议为上层协议提供无状态.无连接.不可靠的服务: 无状态(stateless):指 IP 通信双方不同步传输数据的状态信息,因此所有 IP 数据报的发送.传输和接收都 ...

  8. 【Linux网络编程】TCP 和 UDP 数据报格式详解

    TCP 报文格式 TCP(Transmission Control Protocol 传输控制协议)是一种面向连接的.可靠的.基于字节流的传输层通信协议. TCP 报文段的报头有 10 个必需的字段和 ...

  9. Linux网络编程一步一步学-select详解

    select系统调用是用来让我们的程序监视多个文件描述符(file descriptor)的状态变化的.程序会停在select这里等待,直到被监视的文件描述符有某一个或多个发生了状态改变. selec ...

最新文章

  1. 60条知乎神回复,大部分都比较有道理
  2. java栈实现简易计算器算法
  3. linux c之strncpy函数和strncmp函数最简单使用总结
  4. [JavaWeb-Servlet]IDEA与Tomcat的相关配置
  5. mysql 存储过程 记录是否存在_如何检查MySQL中是否存在存储过程?
  6. 切换输入法默认语言为英文
  7. 张广慧:云计算对游戏开发者的价值
  8. 两步搞定经验模态分解与离散小波变换
  9. tomcat发布asp网站的解决办法(转)
  10. python--Venn图及upsetplot进阶
  11. vue-quill-editor编辑器踩坑
  12. Qtum量子链发布QIP-6,通过预编译合约大幅降低开发成本
  13. Qemu Fuzzer学习
  14. 问卷研究的五类分析思路模板
  15. opencv(三)对图像进行简单算术运算(加减乘除)
  16. latex大斜杠, 除号
  17. 去哪找到高薪工作怎么找
  18. 洛谷P4408 [NOI2003]逃学的小孩
  19. 云服务器使用感受迥漣稅蒟羺怸遯潲佧罧障煓茹棚億辖嗔徟嚼囙
  20. 数字大小写转换(包括金额)

热门文章

  1. 150个超实用的网站,整理成资源库页面分享给大家
  2. Hyper-V的CentOS设置固定IP
  3. 百度网盘提速方法,配合FDM使用效果很好
  4. mac必备老牌下载器!Free Download Manager 6.12.1 中文版
  5. python猪脸识别_别@微信团队了,我用Python给自己戴上了圣诞帽!
  6. SpringWind180926
  7. [HNOI2003]激光炸弹
  8. Ubuntu中安装ClamAV防病毒软件
  9. 专访 Zipkin 项目 Leader:如何用 Zipkin 做好分布式追踪?
  10. 简单的前端网页分享功能怎么做?