TinyWebserver的复现与改进(2):项目的整体框架
上文我们成功运行了代码,本文我们将对项目的整体流程作一下讲解
如果你之前没做过相关的内容,对服务器的⾼并发模型也⼀⽆所知,不建议继续做下去,需要的前置知识有:
- Linux的基本命令(⭐)
- 多进程(⭐)
- 多线程(⭐⭐⭐)
- 网络通信(⭐⭐⭐)
项目的基本流程
我们⾸先还是先看下项⽬的⽂档,看下作者有没有提供代码的框架,有的话就简单了,对着框架图去看代码,可以迅速理清代码的模块组成,快速上⼿其他⼈的代码,然后就可以⾃⼰去写了。
我以项⽬qinguoyi/TinyWebServer at raw_version (github.com)中的框架图为例:

这个webserver流程图详细描述了从接收客户端请求到处理并响应这些请求的一系列复杂过程。下面是对这个流程图的逐步解释:
-
半同步/半反应堆线程池:这是整个webserver的起点,它提前创建了一个线程池(本质上是一个数组),线程池里面有多个子线程,在最开始的时候,由于没有任务,子线程(即上图的工作线程)都处在空闲状态
为什么要使用线程池?
当你需要限制你应用程序中同时运行的线程数时,线程池非常有用。因为启动一个新线程会带来性能开销,每个线程也会为其堆栈分配一些内存等。为了任务的并发执行,我们可以将这些任务任务传递到线程池,而不是为每个任务动态开启一个新的线程 -
epoll监听socket:在主线程中,使用epoll机制来监听socket上的事件(如连接请求)。此时主线程只需要等待有客户端发送数据过来,做出响应,而无需处理具体的任务(这些具体的任务将会由子线程完成)
-
请求队列:当接收到客户端的请求时,这些请求会被放入请求队列中。这个队列一般是用list实现的,并且使用信号量来唤醒等待处理请求的子线程。
这里的信号量可以看作是📜待办通知,它告诉子线程有任务需要做了
而请求队列一般是用list实现,每一个node都可以看作是一个🛠任务,队列中 node的数量 == 信号量
-
处理任务:当信号量来唤醒(即有任务通知了),请求队列中的任务会被取出并处理。本项目中有3种不同的业务需求,如处理HTTP请求、定时器定时关闭长时间没有活动的客户端、日志输出记录
处理任务这部分可以现暂时不用细究,后面学到这个模块时再一个一个来看
服务器编程的基本框架
上面的框架可以更笼统地概括为下图:

其中主线程是I/O处理模块,逻辑单元是一个个子线程,网络存储单元是之前安装的 MySQL
| 模块 | 模块 |
|---|---|
| I/O 处理单元 | 处理客户连接,读写网络数据 |
| 逻辑单元 | 业务进程或线程 |
| 网络存储单元 | 数据库、文件或缓存 |
| 请求队列 | 各单元之间的通信方式 |
- I/O 处理单元是服务器管理客户连接的模块。它通常要完成以下工作:等待并接受新的客户端连接,接收客户端数据,将服务器响应数据返回给客户端。但是数据的收发不在 I/O 处理单元中执行,一般在逻辑单元中执行。
- 一个逻辑单元通常是一个进程或线程(本项目中是线程)。它分析并处理客户数据,然后将结果传递给 I/O 处理单元。服务器通常拥有多个逻辑单元(一般线程池已经创建好了多个逻辑单元),以实现对多个客户任务的并发处理。
- 网络存储单元可以是数据库、缓存和文件,但不是必须的。
- 请求队列是各单元之间的通信工具。I/O 处理单元接收到客户请求时,需要以某种方式通知一个逻辑单元来处理该请求。同样,多个逻辑单元同时访问一个存储单元时,也需要采用某种机制来协调处理多个逻辑单元之间的竞争。请求队列通常被实现为线程池的一部分。
总结
本文介绍了项目的总体框架,理清了工作顺序,下一步将会按照这个顺序梳理代码
相关文章:
TinyWebserver的复现与改进(2):项目的整体框架
上文我们成功运行了代码,本文我们将对项目的整体流程作一下讲解 如果你之前没做过相关的内容,对服务器的⾼并发模型也⼀⽆所知,不建议继续做下去,需要的前置知识有: Linux的基本命令(⭐)多进程…...
R 语言学习教程,从入门到精通,R 字符串(10)
1、R 字符串 R 语言字符串可以使用一对单引号 ’ ’ 或一对双引号 " " 来表示。 单引号字符串中可以包含双引号。 单引号字符串中不可以包含单引号。 双引号字符串中可以包含单引号。 双引号字符串中不可以包含双引号。 以下示例演示来字符串的使用: a …...
QT 简易音乐播放器
目录 放置控件 获取mp3文件 播放音乐 准备工作 加载模块 加载头文件 new一个output对象,Mediaplayer对象 把outpout对象交给mediaplayer对象 给播放器设置音乐 播放 优化 上一曲下一曲功能 双击歌曲播放 获取音乐时长和音乐播放时间 让音乐进度条跟随音乐走 调…...
代码随想录八股训练营day32
代码随想录八股训练营day32 1、synchronized和lock的区别是什么 (1)synchronized和lock的区别是什么 synchronized和Lock都是Java中用于实现线程同步的手段,synchronized是Java的关键字,基于JVM的内置锁实现,可以用于…...
11.面试题——消息队列RabbitMQ
1.RabbitMQ是什么?特点是什么? RabbitMQ是一种开源的消息队列中间件,用于在应用程序之间进行可靠的消息传递。它实现了AMQP(Advanced Message Queuing Protocol)协议,提供了强大的消息处理能力。RabbitMQ的…...
MySQL运维-日志
错误日志 二进制日志 介绍 日志格式 日志查看 日志删除 查询日志 慢查询日志...
synchronized重量级锁的实现原理是怎样的
重量级锁(Heavyweight Locking)是 Java 中 synchronized 关键字的锁机制的一部分,用于在高竞争情况下确保线程的同步。重量级锁主要通过操作系统的线程同步机制实现,通常涉及阻塞线程、上下文切换等开销较大的操作。以下是重量级锁…...
探索 GLTF 的世界:3D 内容的未来
在 3D 内容创作领域,GLTF 正在掀起波澜,成为跨不同平台提供丰富互动体验的未来标准。GL 传输格式 (GLTF) 由 Khronos Group 开发,是一种用于在工具和服务之间传输 3D 模型和场景的开放标准。它设计紧凑、高效且易于集成…...
【深度学习】【语音】TTS, CM-TTS,TTS扩散模型,论文
CM-TTS: Enhancing Real Time Text-to-Speech Synthesis Efficiencythrough Weighted Samplers and Consistency Models CM-TTS: 提高实时文本到语音合成效率 通过加权采样器和一致性模型 Xiang Li 1, Fan Bu 1, Ambuj Mehrish 2, Yingting Li 1, Jiale Han 1, Bo Cheng 1, S…...
【网络协议】网络劫持 - ARP_DNS欺骗篇
前言 网络劫持是一种网络攻击技术,攻击者通过拦截、篡改或重定向数据流量,控制用户的网络通信路径,干扰正常的网络服务。其方式可能包括DNS劫持、ARP欺骗和HTTP劫持等。通过这些手段,攻击者可以窃取敏感信息如个人身份数据和财务信…...
Linux 系统框架分析(一)
一、linux内核结构框图 对内核结构框图有个总体的把握,有助于理解为什么驱动要这样写,为什么写的应用程序所用的C库接口能够产生这么多的事情。 框图可以看出来,linux系统,包括五个系统 一、Linux内核结构介绍 Linux 内核是操作…...
Leetcode 剑指 Offer II 090.打家劫舍 II
题目难度: 中等 原题链接 今天继续更新 Leetcode 的剑指 Offer(专项突击版)系列, 大家在公众号 算法精选 里回复 剑指offer2 就能看到该系列当前连载的所有文章了, 记得关注哦~ 题目描述 一个专业的小偷,计划偷窃一个环形街道上沿街的房屋&a…...
上海冷链配送新篇章 华鼎冷链科技以卓越服务餐饮品牌
在快速发展的上海餐饮连锁行业中,冷链运输作为保障食品安全与品质的关键环节,正迎来前所未有的发展机遇与挑战。华鼎冷链科技作为该领域的佼佼者,正引领着上海乃至全国冷链运输行业的新风尚。 华鼎冷链科技的成功并非一蹴而就。首先ÿ…...
学习鸿蒙-应用市场申请签名
1.需要的文件概念 .cer / .p7b / .p12 / .csr HarmonyOS应用/服务通过数字证书(.cer文件)和Profile文件(.p7b文件)来保证应用/服务的完整性。在申请数字证书和Profile文件前,首先需要通过DevEco Studio来生成密钥&am…...
LayUi插件
文档:日期和时间组件文档 - Layui layDate安装 npm install layui-laydate...
使用tailwindcss轻松实现移动端rem适配
本示例节选自小卷全栈开发实战系列的《Vue3实战》。演示如何用tailwindcss所支持的rem体系轻松实现一个仿b站移动端头部导航栏rem适配。 友情声明 学习分享不易,如果小伙伴觉得有帮助,点赞支持下。满30赞,将随文附赠录屏讲解,感谢…...
2021-11-08 51单片机2位秒表启动清零
缘由c51单片机,程序,仿真图,求帮助-编程语言-CSDN问答 #include "REG52.h"sbit K1 P1^0; sbit K2 P1^1; sbit K3 P1^2; sbit K4 P1^3; sbit P1_0P2^0; sbit P1_1P2^1; sbit P1_2P2^2; sbit P1_3P2^3; sbit P1_4P2^4; sbit P1_…...
谈基于大语言模型的图数据库路径检索
随着微软已经开源了GraphRAG项目的代码,基于图数据库的RAG 热度迅速升温。关注基于大语言模型与图模型数据库相结合的技术的人多了起来。 本文提出了一种类似人工搜索的“顺藤摸瓜”方法,实现图数据库的智能搜索方法。 本地私有数据存储和查询 本地私有…...
XHTML 简介
XHTML 简介 XHTML,即“可扩展超文本标记语言”(eXtensible HyperText Markup Language),是一种基于XML的标记语言,旨在取代HTML作为网页内容的标准格式。XHTML继承了HTML的基本结构,但更加严格和规范&…...
驱动开发系列10 - Linux Graphics 图形栈介绍
目录 一:Linux 图形栈总体结构 1. 整体图形栈: 2. 现代3D图形栈: 二:Xorg 介绍 Xorg 概述: Xorg的发展历史: Xorg绘制原理: Xorg的缺点: 三:Wayland 介绍 一:Linux 图形栈总体结构 1. 整体图形栈: 应用程序->桌面环境->GUI框架->Display Client->Displ…...
K8S认证|CKS题库+答案| 11. AppArmor
目录 11. AppArmor 免费获取并激活 CKA_v1.31_模拟系统 题目 开始操作: 1)、切换集群 2)、切换节点 3)、切换到 apparmor 的目录 4)、执行 apparmor 策略模块 5)、修改 pod 文件 6)、…...
MVC 数据库
MVC 数据库 引言 在软件开发领域,Model-View-Controller(MVC)是一种流行的软件架构模式,它将应用程序分为三个核心组件:模型(Model)、视图(View)和控制器(Controller)。这种模式有助于提高代码的可维护性和可扩展性。本文将深入探讨MVC架构与数据库之间的关系,以…...
土地利用/土地覆盖遥感解译与基于CLUE模型未来变化情景预测;从基础到高级,涵盖ArcGIS数据处理、ENVI遥感解译与CLUE模型情景模拟等
🔍 土地利用/土地覆盖数据是生态、环境和气象等诸多领域模型的关键输入参数。通过遥感影像解译技术,可以精准获取历史或当前任何一个区域的土地利用/土地覆盖情况。这些数据不仅能够用于评估区域生态环境的变化趋势,还能有效评价重大生态工程…...
成都鼎讯硬核科技!雷达目标与干扰模拟器,以卓越性能制胜电磁频谱战
在现代战争中,电磁频谱已成为继陆、海、空、天之后的 “第五维战场”,雷达作为电磁频谱领域的关键装备,其干扰与抗干扰能力的较量,直接影响着战争的胜负走向。由成都鼎讯科技匠心打造的雷达目标与干扰模拟器,凭借数字射…...
select、poll、epoll 与 Reactor 模式
在高并发网络编程领域,高效处理大量连接和 I/O 事件是系统性能的关键。select、poll、epoll 作为 I/O 多路复用技术的代表,以及基于它们实现的 Reactor 模式,为开发者提供了强大的工具。本文将深入探讨这些技术的底层原理、优缺点。 一、I…...
CSS设置元素的宽度根据其内容自动调整
width: fit-content 是 CSS 中的一个属性值,用于设置元素的宽度根据其内容自动调整,确保宽度刚好容纳内容而不会超出。 效果对比 默认情况(width: auto): 块级元素(如 <div>)会占满父容器…...
Netty从入门到进阶(二)
二、Netty入门 1. 概述 1.1 Netty是什么 Netty is an asynchronous event-driven network application framework for rapid development of maintainable high performance protocol servers & clients. Netty是一个异步的、基于事件驱动的网络应用框架,用于…...
AirSim/Cosys-AirSim 游戏开发(四)外部固定位置监控相机
这个博客介绍了如何通过 settings.json 文件添加一个无人机外的 固定位置监控相机,因为在使用过程中发现 Airsim 对外部监控相机的描述模糊,而 Cosys-Airsim 在官方文档中没有提供外部监控相机设置,最后在源码示例中找到了,所以感…...
C/C++ 中附加包含目录、附加库目录与附加依赖项详解
在 C/C 编程的编译和链接过程中,附加包含目录、附加库目录和附加依赖项是三个至关重要的设置,它们相互配合,确保程序能够正确引用外部资源并顺利构建。虽然在学习过程中,这些概念容易让人混淆,但深入理解它们的作用和联…...
STM32HAL库USART源代码解析及应用
STM32HAL库USART源代码解析 前言STM32CubeIDE配置串口USART和UART的选择使用模式参数设置GPIO配置DMA配置中断配置硬件流控制使能生成代码解析和使用方法串口初始化__UART_HandleTypeDef结构体浅析HAL库代码实际使用方法使用轮询方式发送使用轮询方式接收使用中断方式发送使用中…...
