【muduo源码学习】one-loop-per-thread核心原理

在 TCP 网络编程中,这里我们特指在单机的环境下,主要关注两件事。第一,如何正确的处理TCP的连接和断开,以及正确处理数据的收发;在错综复杂的网络环境中,这并非易事,涉及很多细节。第二,如何榨干机器的性能,即如何让单台机器在已有的硬件条件下处理尽可能多的连接请求;这需要设计一种高效的网络模型,这是本文讨论的主题,即在 muduo 网络库源码的学习基础上,总结和讨论。

下面进入本文的主题。

在TCP网络编程中,我们关注的核心是,在一个小的时间片段中,如何能够处理更多的并发连接。这主要可以从三个方面展开,而从一个服务端程序的性能指标来看,这三个方面分别为:响应时间、吞吐量和并发连接数。

  • 响应时间。响应时间是指请求发送到收到响应的时间。从程序本身来看,当收到客户端发来的请求时,TCP服务端需要能够立马处理,并将处理结果立马发送回客户端。更具体地,在面对短时间内有大量的请求到来时,TCP服务端要做尽可能地做到不阻塞在某个或某些请求处理上。这表现为,在错综复杂的网络环境中,数据的收发是不确定性,TCP服务端不能阻塞在socket上的读写上,这就要求socket是非阻塞的(nonblocking IO)。
  • 吞吐量。吞吐量是指单位时间内处理的请求数量。我们希望每个单机的TCP服务程序在单位时间内能够处理尽可能多的请求,这对于单核的CPU很容易就达到瓶颈,而对于多核的CPU,我们希望尽可能把每个核都跑满,使其处理充分多的请求,这就要求TCP服务程序具有很好的多线程网络模型,而下文中介绍的 one loop per thread 网络模型就可以很好的和多线程结合。
  • 并发连接数。并发连接数是指服务程序同时能够处理的连接数量。每个连接最少需要一定的内存资源,因此并发连接数会受计算机硬件的影响;此外每个连接至少需要一个socket文件描述符,而操作系统中的文件描述符数量是有限的,因此并发连接数会受到操作系统软件资源的影响。此外,从TCP服务程序本身来看,TCP服务程序可以同时保持很多连接,但在同一时刻处理这些已连接的请求的数量是少于总连接的数量的,同时TCP服务程序要需要处理源源不断带来的新连接,以及因为连接超时等原因关闭的连接,这就要求我们使用IO复用技术(IO multiplexing)。

小结一下,为降低响应时间,需要使用 nonblocking IO;为并发连接数尽可能大,需要使用 IO multiplexing;为了提高吞吐量,在程序上需要设计良好的多线程网络模型。下面就正式介绍 one loop per thread 网络模型,它是基于 nonblocking IO 和 IO multiplexing 的。

one loop per thread 网络模型,也称为 Reactor 模型。loop指事件循环,将文件描述符可读称为一个可读事件,将文件描述符可写称为一个可写事件,在TCP网络编程中,我们重点关注socket文件描述符上的读写事件。事件循环是指监控文件描述符上的读写事件,当有文件描述符变得可读或可写时,理解为发生了一次事件循环,即检测到一次事件发生。事件循环是依赖于 IO multiplexing 的。综上,one loop per thread 指每个线程中只有一个事件循环。

如下图所示,先来看下在单线程下,one loop per thread 网络模型长什么样子。
在这里插入图片描述

单线程下 one loop per thread 网络模型的TCP连接处理流程:

  • 服务端阻塞在 IO multiplexing 函数调用,等待客户端的请求到来。
  • 当客户端发送请求给服务端,IO multiplexing 函数检测到读事件,解除阻塞,然后获取产生读事件的 socket 文件描述符,从socket文件描述符上读取数据进行处理。在 IO multiplexing 函数中监控的 socket 文件描述有两类,一类是已连接的 socekt 文件描述符,一类是监听是否有新连接到来的 socket 文件描述符。
    • 对于监听socket上的读事件,调用 accept() 函数接收一个新的连接请求,并获取新连接的 socket 文件描述符,然后将其注册到 IO multiplexing 函数中。
    • 对于已连接的 socket 上的读事件,进行 read() --> 业务处理 --> write() 的处理流程。

one loop per thread 网络模型通过 nonblocking IO + IO multiplexing 可以很好的同时处理新连接和已连接,但存在的问题也显而易见,因为是单线程,你处理能力受限,且当已连接的处理比较耗时,新连接的响应时间就会受到影响。若已连接的处理比较耗时,比如是CPU密集计算任务,一种解决方案是,另起线程做CPU密集祭祀按任务,不让其影响IO线程,从而影响响应时间。当然这在单线程环境下都无从说起。

发挥 one loop per thread 网络模型能力的场合时多线程环境,通过将新连接的处理和已连接的处理分发到不同线程,来提高吞吐量。其本质是让已连接的处理不会影响新连接的处理。多线程下的 one loop per thread 网络模型如下图所示。
在这里插入图片描述

多线程 one loop per thread 网络模型下,每个线程中运行一个 loop,且每个线程最多运行一个 loop。在这个网络模型下,有一个主线程,有的博客中也称为主Reactor(Main Reactor)。主线程主要干两件事,第一,管理监听socket,当有新连接到来,即监听socket可读,调用 accept() 建立一个新连接;第二,获取新连接的 socket 后,将其分发到一个子线程中的 IO multiplexing 函数中,之后这个已连接 socket 上的读写事件主线程就不再负责,被分发到的子线程始终管理着这个已连接socket上的读写事件,直到这个连接关闭。

多线程的 one loop per thread 网络模型的优点:

  • 将新连接处理和已连接处理分离在不同的线程处理,兼顾服务程序的响应事件和吞吐量。
  • 监控 socket 上读写事件的线程是固定的,即不存在A线程监控读事件B线程监控写事件的情况,事件处理的流程简单。
  • 任务在线程之间的调配安全简单。在A线程调用B线程管理的socket上的回调函数,最终会转入B线程执行调用。(将在《muduo源码分析之Channel、EventLoop和Selector》的文章中详细介绍)

总结: 上述描述的 one loop per thread 网络模型主要涉及网络的IO,也即主要关心 socket 的读写事件,这是网络库关心的核心问题之一。因此,有时又将具有事件循环的线程称为IO线程。一个高效的网络库的核心工作是要能够处理足够大的并发量,即IO事件,当请求中涉及CPU密集计算任务时,不能让其在IO线程中占用过多的CPU资源,这样会影响到IO线程上的其他连接,一种解决办法是,为CPU密集计算任务开辟单独的线程或线程池,通过例如消息队列的形式将密集计算任务分发给这些线程, one loop per thread 模型可能很轻松进行这样的结合。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/819742.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【JAVA基础篇教学】第十七篇:Java单元测试

博主打算从0-1讲解下java基础教学,今天教学第十七篇:Java单元测试。 单元测试和集成测试是软件开发过程中至关重要的一部分,它们可以帮助确保代码的质量和稳定性。下面我将为您提供详细说明和代码案例。 一、单元测试(Unit Test…

Leetcode 221. 最大正方形

心路历程: 这道题是一个动态规划题,但是其实递推关系很难想到,如下图所示: MDP建模: 状态:以i,j为右下角的正方形 动作候选集:这道题的动作候选集其实是是否选择其左上角邻接的三个位置&#x…

11.范式与反范式设计

范式 1.问题 MySQL的库表设计,在很多时候我们都是率性而为,往往在前期的设计中考虑不全面,同时对于库表结构的划分也并不明确,所以很多时候在开发过程中,代码敲着敲着会去重构某张表结构,甚至大面积重构多…

深圳比创达电子EMC|EMC电磁兼容性:电子设备稳定运行的保障

随着科技的飞速发展,电子设备在人们的日常生活中发挥着越来越重要的作用。然而,随之而来的电磁干扰问题也日益突出。电磁兼容性(EMC)作为衡量电子设备在电磁环境中正常工作能力的关键指标,其重要性不言而喻。 一、EMC…

IP地址是随着网络变化的吗?

IP地址,即互联网协议地址,是分配给每个联网设备或网络接口的数字标签。它在网络通信中起着至关重要的作用,是设备之间互相识别和通信的基础。然而,关于IP地址是否随着网络变化,这是一个值得深入探讨的问题,…

深度残差收缩网络中,使用 Sigmoid 函数的用意在哪?

在深度残差收缩网络中,使用 Sigmoid 函数将输出归一化到 0 和 1 之间的目的是为了限制输出值的范围,并且使得输出可以被解释为概率。这个 Sigmoid 函数的输出可以被看作是一个置信度或者概率的度量,表示某个事件发生的可能性。 在设置阈值时…

详解playwright 官方Javascript demo(适合小白)

如果大家刚上手playwright,并看到了Javascript脚本的官方demo,代码如下: const { webkit } require(playwright);(async () > {const browser await webkit.launch();const page await browser.newPage();await page.goto(http://what…

开放式耳机怎么选?五大市场热卖爆款推荐!

近年来,开放式耳机风潮席卷市场,各大知名品牌纷纷推出新品,以满足消费者的需求。相较于传统的入耳式耳机,开放式耳机凭借其独特的佩戴方式,受到了广大消费者的热烈追捧。它不仅有效避免了长时间佩戴带来的耳道不透气、…

【数据结构】栈的实现

👑个人主页:啊Q闻 🎇收录专栏:《数据结构》 🎉前路漫漫亦灿灿 前言 栈是一种特殊的线性表,我们在有了顺序表和链表的知识的基础上,再来学习栈,掌握起来就更轻松了…

所有可能的真二叉树(Lc894)——记忆化搜索

给你一个整数 n ,请你找出所有可能含 n 个节点的 真二叉树 ,并以列表形式返回。答案中每棵树的每个节点都必须符合 Node.val 0 。 答案的每个元素都是一棵真二叉树的根节点。你可以按 任意顺序 返回最终的真二叉树列表。 真二叉树 是一类二叉树&#…

【24年物联网华为杯】赛题分析与初步计划

赛事介绍 官网链接:2024 年全国大学生物联网设计竞赛 (sjtu.edu.cn) 含金量:属于A类赛事 (注意:很多搜索结果的序号是按照选入时间排列的,与含金量无关,华为杯是23年选入的) Kimi Chat: 全国…

开源模型应用落地-LangChain试炼-CPU调用QWen1.5(一)

一、前言 尽管现在的大语言模型已经非常强大,可以解决许多问题,但在处理复杂情况时,仍然需要进行多个步骤或整合不同的流程才能达到最终的目标。然而,现在可以利用langchain来使得模型的应用变得更加直接和简单。 通过langchain框…

【学习笔记十二】EWM上架仓位确定逻辑及操作演示

一、前言 关于EWM上架仓位确定的过程,我在【学习笔记十一】EWM上架目标仓位确定过程及配置-CSDN博客中讲到了 EWM根据仓库类型(storage type)、仓库分区(storage section)和上架策略(putaway strategies&…

机器学习算法快速入门

文章目录 0.简介1.常用术语1) 模型2) 数据集3) 样本&特征4) 向量5) 矩阵6)假设函数&损失函数7)拟合&过拟合&欠拟合 2.线性回归3.梯度下降求极值4.Logistic回归算法(分类问题)5.KNN最邻近分类算法6.朴素贝叶斯分类算法7.决策树…

SAP 技巧篇:解决下拉菜单不显示前缀编码问题

事务代码 BP创建主数据选择组时,组前面不显示英文分组,或者其他界面不显示对应英文分组” 01 — 背景需求 BP等事务代码进来不显示前面系统英文分组 02 — 实现 返回SAP GUI找到选项>可视化1>控件全部打钩 先打钩:在下拉列表内显示…

Golang | Leetcode Golang题解之第29题两数相除

题目: 题解: func divide(dividend, divisor int) int {if dividend math.MinInt32 { // 考虑被除数为最小值的情况if divisor 1 {return math.MinInt32}if divisor -1 {return math.MaxInt32}}if divisor math.MinInt32 { // 考虑除数为最小值的情…

汽车抗疲劳驾驶测试铸铁试验底座技术要求有哪些

铸铁平台试验台底座的主要技术参数要求 1、 试验台底座设计制造符合JB/T794-1999《铸铁平板》标准。 2、 试验铁底板及所有附件的计量单位全部采用 单位(SI)标准。 3、铸铁平台平板材质:用细密的灰口铸铁HT250或HT200,强度符…

U盘怎么加密?U盘加密的方法有哪些?

U盘作为一种便携式的存储设备,广泛应用于日常生活和工作中。但由于其易于携带和使用的特性,U盘中的数据也面临着被未经授权访问的风险。因此,对U盘进行加密成为了保护数据安全的重要措施。本文将介绍几种常见的U盘加密方法,帮助用…

【C++学习】C++4种类型转换详解

这里写目录标题 🚀C语言中的类型转换🚀为什么C需要四种类型转换🚀C强制类型转换🚀static_cast🚀**reinterpret_cast**🚀const_cast与volatile🚀dynamic_cast 🚀C语言中的类型转换 在…

腾讯EdgeOne产品测评体验—Web服务全能一体化服务,主打一步到位

前言 现在网络Web攻击真的防不胜防啊,相信有很多独狼开发者自己建站,租个云服务器,一部署自己的服务,每隔一段时间内测和网站总有一个要崩。自己感觉难受不说,网站稍微有点要出头的时候,数不清的访问攻击就…