【C++高并发服务器WebServer】-17:阻塞/非阻塞和同步/异步、五种IO模型、Web服务器

在这里插入图片描述

本文目录

  • 一、阻塞/非阻塞、同步/异步
    • 1.1 辨析
    • 1.2 异步io接口
  • 二、五种IO模型
    • 2.1 阻塞 blocking 模型
    • 2.2 非阻塞 NIO 模型
    • 2.3 IO多路复用
    • 2.4 信号驱动Signal-driven
    • 2.5 异步
  • 三、Web Sever 网页服务器
    • 3.1 HTTP的请求响应步骤
    • 3.2 HTTP请求与响应报文格式
    • 3.3 HTTP请求方法
    • 3.4 HTTP状态码
    • 3.4 服务器编程基本框架

一、阻塞/非阻塞、同步/异步

1.1 辨析

本节的阻塞与非阻塞、同步与异步均指网络I/O

首先我们明确,典型的一次IO的两个阶段是 数据就绪数据读写

数据就绪是指根据系统IO操作的就绪状态,从而有阻塞和非阻塞的说法。
数据读写是指根据应用程序和内核的交互方式,从而有同步和异步的说法。

我们可以以下面这个图进行对应的说明。

在这里插入图片描述
阻塞:当调用IO的函数,当数据还没有准备好(对方可能还没有发送过来),那么就会处于阻塞,这个时候线程会处于一个挂起的状态。线程挂起就不会再占用cpu的资源了。

非阻塞:当调用IO的函数,当数据还没有准备好(对方可能还没有发送过来),程序并不会挂起,而是会立即返回,并且继续往下执行,这个时候需要通过返回值进行一个判断(判断数据是否发过来了)。

比如之前接触过的ssize_t recv(int sockfd,void * buf,size_t len,int flags)这个函数(默认是阻塞的属性)。

sockfd就对应了操作系统在内核的接收缓冲区,假设recv设置了阻塞属性,那么如果对方已经把数据发过来,就不会处于阻塞,但是如果数据没有到达,就会把线程挂起。

假设如果recv函数设置了非阻塞的属性,当没有数据到达,那么函数会立即返回一个数值,我们需要判断这个数值,判断一些情况。判断的情况现在进行对应的说明(例如当返回-1时,需要对EINTR、EAGAIN、EWOULDBLOCK等进行特判,这几个情况并不是错误)。

int size = recv(sockfd,buf,1024,0) ,如果返回size=-1,就代表出错了,但是会设置对应的错误的errno

但是当是某些情况的时候,需要我们进行特殊处理。比如EINTR,当信号产生后会中断程序,中断后再回来之后会返回-1,并且标记错误为EINTR)。还比如EAGAIN / EWOULDBLOCK,表示没有得到数据,需要再读一次。

如果返回size=0,代表读取到数据的末尾,对方连接关闭。

如果返回size>0,代表读取到了多少的数据。

在这里插入图片描述
接下来来讲讲同步异步。

recv是一个“同步”函数,因为是需要我们自己去调用和读取到buf中(个人见解),需要等sockfd中数据复制到buf中后才会返回,并且在没有完成之前,并不会返回,此时程序并不会往下继续执行。

简单来说就是需要我们应用层自己去调用这个recv完成相关的读写。

异步一般需要操作系统给我们提供异步IO接口,一般需要把sockfd、buf、通知方式给操作系统,接下来应用程序可以继续往下执行其他操作,当内环缓冲区有数据之后,操作系统会自动帮我们把这个数据放到buf当中,然后再通知我们(通过sigio信号,告知我们buf的数据已经准备好了)。

也就是说,在同步I/O操作中,应用程序负责主动调用I/O函数来请求数据传输。以recv函数为例,应用程序调用recv后,如果数据尚未准备好,recv会阻塞当前线程,直到数据从套接字缓冲区复制到用户提供的缓冲区中。这种阻塞行为意味着应用程序在等待I/O操作完成期间不能执行其他任务。同步I/O通常适用于数据传输量不大、实时性要求不高的场景。

与同步I/O不同,异步I/O允许应用程序在发起I/O请求后立即返回,继续执行其他任务,而不必等待I/O操作完成。操作系统会在数据准备好后,通过某种机制(如信号、回调函数或事件通知)告知应用程序。这种机制使得应用程序可以在数据到达时得到通知,而不必不断轮询检查。

异步I/O通常需要操作系统提供专门的异步I/O接口,如aio_read、aio_write等。这些接口允许应用程序指定I/O操作的参数,包括缓冲区地址、数据长度等,并将控制权返回给应用程序。当I/O操作完成时,操作系统会通过注册的回调函数或信号处理程序通知应用程序。

异步I/O通常能更好地利用系统资源,因为它允许应用程序在等待I/O操作完成时执行其他任务,从而提高程序的并发性和响应性。但异步I/O的编程模型通常比同步I/O更复杂,因为它需要处理回调函数、信号处理等机制,这可能会增加代码的复杂性和调试难度。

同步I/O:适用于I/O操作不频繁、数据量不大、实时性要求不高的场景。例如,简单的文件读写、少量的数据传输等。

异步I/O:适用于需要处理大量并发连接、数据量大、实时性要求高的场景。例如,高性能的网络服务器、实时数据处理系统等。

陈硕大神说过一句话:处理IO的时候,阻塞和非阻塞都是同步IO(都需要我们用户自己去操作数据),只有使用了特殊的API才是异步IO(比如linux中的aio_read接口)

epoll并不是异步的,这个需要弄清楚。明确这个数据是不是我们应用程序去主动操作就行,如果是,那就是同步,如果是操作系统帮我们直接搬运好到buf中,那就是异步。(IO多路复用都是同步的。)

在这里插入图片描述
一个典型的网络IO接口调用,分为两个阶段,分别是“数据就绪” 和 “数据读写”,数据就绪阶段分为阻塞和非阻塞,表现得结果就是,阻塞当前线程或是直接返回。

同步表示A向B请求调用一个网络IO接口时(或者调用某个业务逻辑API接口时),数据的读写都是由请求方A自己来完成的(不管是阻塞还是非阻塞);异步表示A向B请求调用一个网络IO接口时(或者调用某个业务逻辑API接口时),向B传入请求的事件以及事件发生时通知的方式,A就可以处理其它逻辑了,当B监听到事件处理完成后,会用事先约定好的通知方式,通知A处理结果。

1.2 异步io接口

man aio_read来查看linux系统文档中的异步io说明。

可以看到其函数的参数是一个类型为aiocb *aiocbp的一个结构体。

在这里插入图片描述

结构体定义如下,是一个异步IO的控制块。
(异步一般是跟非阻塞搭配使用的。)

在这里插入图片描述

二、五种IO模型

2.1 阻塞 blocking 模型

很简单来阐述,就是必须等待函数返回,才能往下执行。
在这里插入图片描述

2.2 非阻塞 NIO 模型

非阻塞等待,每隔一段时间就去检测I0事件是否就绪。没有就绪就可以做其他事。非阻塞I/0执行系统调用总是立即返回,不管事件是否已经发生,若事件没有发生,则返回-1,此时可以根据 errno 区分这两种情况,对于accept,recv和send,事件未发生时,errno通常被设置成 EAGAIN。

在这里插入图片描述

2.3 IO多路复用

Linux 用 selectpoll/epoll 函数实现 IO复用模型,这些函数也会使进程阻塞,但是和阻塞IO所不同的是这些函数可以同时阻塞多个IO操作。而且可以同时对多个读操作、写操作的!0函数进行检测。直到有数据可读或可写时,才真正调用I0操作函数。

在这里插入图片描述

2.4 信号驱动Signal-driven

Linux 用套接口进行信号驱动 IO,安装一个信号处理函数,进程继续运行并不阻塞,当IO事件就绪,进程收到SIGIO 信号,然后处理 IO 事件。

内核在第一个阶段是异步,在第二个阶段是同步;与非阻塞IO的区别在于它提供了消息通知机制,不需要用户进程不断的轮询检查,减少了系统API的调用次数,提高了效率。

在这里插入图片描述

2.5 异步

Linux中,可以调用 aio_read 函数告诉内核描述字缓冲区指针和缓冲区的大小、文件偏移及通知的方式,然后立即返回,当内核将数据拷贝到缓冲区后,再通知应用程序。
在这里插入图片描述

三、Web Sever 网页服务器

WebServer就是一个服务器软件程序,或者运行这个服务器软件的硬件(计算)。主要是通过HTTP协议与客户端进行通信,接收请求,然后做出HTTP响应。

通常用户使用 Web 浏览器与相应服务器进行通信。在浏览器中键入“域名"或"IP地址:端口号”,浏览器则先将你的域名解析成相应的 IP 地址或者直接根据你的IP地址向对应的 Web 服务器发送一个 HTTP 请求。这一过程首先要通过 TCP 协议的三次握手建立与目标 Web 服务器的连接,然后 HTTP 协议生成针对目标 Web 服务器的 HTTP 请求报文,通过 TCP、IP 等协议发送到目标 Web 服务器上。

HTTP假定其下层协议必须提供可靠的传输。因此,任何能够提供这种保证的协议都可以被其使用,因此也就是其在TCP/IP协议族使用TCP作为其传输层。

3.1 HTTP的请求响应步骤

在这里插入图片描述

3.2 HTTP请求与响应报文格式

在这里插入图片描述
在这里插入图片描述

3.3 HTTP请求方法

GET:用于请求指定资源的数据。GET 请求应该只被用于获取数据,并且不会对服务器上的数据产生任何影响。

POST:用于向指定资源提交数据,通常导致服务器上的数据被创建或修改。POST 请求通常用于表单提交。

PUT:用于将请求体中包含的数据替换指定资源的全部内容。如果该资源不存在,服务器可能会根据请求创建新资源。

DELETE:用于删除指定的资源。

HEAD:类似于 GET 请求,但不返回响应体。HEAD 请求用于获取资源的元数据,如 HTTP 头信息。

OPTIONS:用于获取目标资源所支持的通信选项。这个方法经常用于跨源资源共享(CORS)请求,以确定服务器支持哪些 HTTP 方法。

PATCH:用于对已知资源进行部分修改。与 PUT 不同,PATCH 通常用于对资源进行小的、局部的修改。

CONNECT:将连接改为管道方式的代理请求。CONNECT 方法主要用于创建隧道,例如,在代理服务器上建立 SSL 加密通道。

3.4 HTTP状态码

在这里插入图片描述

3.4 服务器编程基本框架

I/O处理单元是负责客户端连接,读写网络数据。逻辑单元是业务进程或者线程。网络存储单元是指数据库、文件、缓存等。请求队列则是指各单元之间的通信方式。

IO处理单元是服务器管理客户连接的模块。它通常要完成以下工作:等待并接受新的客户连接,接收客户数据,将服务器响应数据返回给客户端。但是数据的收发不一定在 1/0 处理单元中执行,也可能在逻辑单元中执行,具体在何处执行取决于事件处理模式。

一个逻辑单元通常是一个进程或线程。它分析并处理客户数据,然后将结果传递给 IO 处理单元或者直接发送给客户端(具体使用哪种方式取决于事件处理模式)。服务器通常拥有多个逻辑单元,以实现对多个客户任务的并发处理。

网络存储单元可以是数据库、缓存和文件,但不是必须的。

请求队列是各单元之间的通信方式的抽象。I/0 处理单元接收到客户请求时,需要以某种方式通知一个逻辑单元来处理该请求。同样,多个逻辑单元同时访问一个存储单元时,也需要采用某种机制来协调处理竞态条件。请求队列通常被实现为池的一部分。
在这里插入图片描述

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

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

相关文章

【MySQL例题】我在广州学Mysql 系列——有关数据备份与还原的示例

ℹ️大家好,我是练小杰,今天周二,明天就是元宵节了呀!!😆 俗话说“众里寻他千百度。蓦然回首,那人却在,灯火阑珊处。” 本文主要对数据库备份与还原的知识点例题学习~~ 前情回顾&…

自动化xpath定位元素(附几款浏览器xpath插件)

在 Web 自动化测试、数据采集、前端调试中,XPath 仍然是不可或缺的技能。虽然 CSS 选择器越来越强大,但面对复杂 DOM 结构时,XPath 仍然更具灵活性。因此,掌握 XPath,不仅能提高自动化测试的稳定性,还能在爬…

【并发控制、更新、版本控制】.NET开源ORM框架 SqlSugar 系列

系列文章目录 🎀🎀🎀 .NET开源 ORM 框架 SqlSugar 系列 🎀🎀🎀 文章目录 系列文章目录一、并发累计(累加)1.1 单条批量累计1.2 批量更新并且字段11.3 批量更新并且字段list中对应的…

数据存储和操作:数据管理的基石

在数据管理的庞大体系中,数据存储和操作是确保数据可用性和完整性的关键环节。它不仅涉及数据的物理存储,还包括数据的管理、维护和优化。今天,让我们深入《DAMA数据管理知识体系指南(第二版)》的第六章,一…

Redis 数据类型 Hash 哈希

在 Redis 中,哈希类型是指值本⾝⼜是⼀个键值对结构,形如 key "key",value { { field1, value1 }, ..., {fieldN, valueN } },Redis String 和 Hash 类型⼆者的关系可以⽤下图来表⽰。 Hash 数据类型的特点 键值对集合…

支持向量机原理

支持向量机(简称SVM)虽然诞生只有短短的二十多年,但是自一诞生便由于它良好的分类性能席卷了机器学习领域。如果不考虑集成学习的算法,不考虑特定的训练数据集,尤其在分类任务中表现突出。在分类算法中的表现SVM说是排…

zy.21

PHP(续) PHP代码执行漏洞 1.PHP中代码漏洞的概念 代码执行漏洞就是在代码中若存在eval、assert等能将所接收的参数作为代码去执行,并且拼接的内容可被访问者控制,也就是把传入的参数给拼接进去了,造成了额外的代码执行,也就造成了代码执行漏洞。(大概原理&#x…

LSTM 学习笔记 之pytorch调包每个参数的解释

0、 LSTM 原理 整理优秀的文章 LSTM入门例子:根据前9年的数据预测后3年的客流(PyTorch实现) [干货]深入浅出LSTM及其Python代码实现 整理视频 李毅宏手撕LSTM [双语字幕]吴恩达深度学习deeplearning.ai 1 Pytorch 代码 这里直接调用了nn.l…

React - 事件绑定this

在 React 中,this 的绑定是一个常见问题,尤其在类组件中使用事件处理函数时。JavaScript 中的 bind 函数用于设置函数调用时 this 的值。 bind 函数的作用 bind() 方法创建一个新的函数,当被调用时,其 this 关键字被设置为提供的…

Web3 的虚实融合之路:从虚拟交互到元宇宙构建

在这个数字技术日新月异的时代,我们正站在 Web3 的门槛上,见证着互联网的又一次革命。Web3 不仅仅是技术的迭代,它代表了一种全新的交互方式和价值创造模式。本文将探讨 Web3 如何推动虚拟交互的发展,并最终实现元宇宙的构建&…

Kafka简单使用

说明:kafka是一款消息中间件,可实现微服务之间的异步调用。本文介绍kafka的简单使用。windows操作系统下的kafka安装,参考下面这篇文章 Kafka安装 启动 按照上面博客的介绍,使用CMD命令启动,如下: Demo …

【原创精品】基于Springboot3+Vue3的学习计划管理系统

大家好,我是武哥,最近给大家手撸了一个基于SpringBoot3Vue3的学习计划管理系统,可用于毕业设计、课程设计、练手学习,系统全部原创,如有遇到网上抄袭站长的,欢迎联系博主~ 项目演示视频 https://www.bili…

C++引用深度详解

C引用深度详解 前言1. 引用的本质与核心特性1.1 引用概念1.2 核心特性 2. 常引用与权限控制2.1 权限传递规则2.2 常量引用2.3 临时变量保护1. 样例2. 样例3. 测试 三、引用使用场景分析3.1 函数参数传递输出型参数避免多级指针高效传参 3.2 做函数返回值正确使用危险案例 4. 性…

本地部署Deepseek R1

使用Ollama open-webui部署Deepseek R1 一、安装Ollama 官网地址:https://ollama.com/,点击下载按钮选择windows版本。并安装 打开命令提示符输入ollama,出现一下提示命令表示ollama安装完成 二、使用Ollama下载deepseek R1不同模型 打开o…

MATLAB 生成脉冲序列 pulstran函数使用详解

MATLAB 生成脉冲序列 pulstran函数使用详解 目录 前言 一、参数说明 二、示例一 三、示例二 总结 前言 MATLAB中的pulstran函数用于生成脉冲序列,支持连续或离散脉冲。该函数通过将原型脉冲延迟并相加,生成脉冲序列,适用于信号处理和系统…

机器学习(李宏毅)——self-Attention

一、前言 本文章作为学习2023年《李宏毅机器学习课程》的笔记,感谢台湾大学李宏毅教授的课程,respect!!! 二、大纲 何为self-Attention?原理剖析self-Attention VS CNN、RNN、GNN 三、何为self-Attenti…

RagFlow + Docker Desktop + Ollama + DeepSeek-R1本地部署自己的本地AI大模型工具

前期准备 首先,我们需要下载 Ollama 以及配置相关环境。 Ollama 的 GitHub仓库 (https://github.com/ollama/ollama)中提供了详细的说明,简单总结如下: Step1:下载 Ollama 下载(https://ollama.com/dow…

【数据结构】双向链表(真正的零基础)

链表是一种物理存储单元上非连续、非顺序的存储结构。数据元素的逻辑顺序是通过指针的链接来实现的!在上篇我们学习了单向链表,而单向链表虽然空间利用率高,插入和删除也只需改变指针就可以达到!但是我们在每次查找、删除、访问..…

网络编程-day5-sqlite3数据库

思维导图 服务器 #include <stdio.h> #include <string.h> #include <unistd.h> #include <stdlib.h> #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #include <pthread.h> #include <semaphore.h>…

Spring AI 介绍

文章来源&#xff1a;AI 概念 (AI Concepts) _ Spring AI1.0.0-SNAPSHOT中文文档(官方文档中文翻译)|Spring 教程 —— CADN开发者文档中心 本节介绍 Spring AI 使用的核心概念。我们建议仔细阅读它&#xff0c;以了解 Spring AI 是如何实现的。 模型 AI 模型是旨在处理和生成…