免费的网站开发工具/网站收录查询工具

免费的网站开发工具,网站收录查询工具,做网站需要多大的图片,网站服务器怎么做安全防护文章目录 2.5.1 io_uring1. 对比1. select、poll、epoll 对比表格2. 关键特性说明:3. 应用场景 2. 异步io1. 频繁copy2. 如何做到线程安全 3. io_uring1. 实现2. 关键点:3. 问题1. Reactor 与 Proactor 的三点不同2. epoll 与 io_uring 的区别 2.5.1 io_…

文章目录

  • 2.5.1 io_uring
    • 1. 对比
      • 1. select、poll、epoll 对比表格
      • 2. 关键特性说明:
      • 3. 应用场景
    • 2. 异步io
      • 1. 频繁copy
      • 2. 如何做到线程安全
    • 3. io_uring
      • 1. 实现
      • 2. 关键点:
      • 3. 问题
        • 1. Reactor 与 Proactor 的三点不同
        • 2. epoll 与 io_uring 的区别

2.5.1 io_uring

1. 对比

1. select、poll、epoll 对比表格

维度selectpollepoll
最大描述符数默认 1024(硬编码)无限制(受系统资源约束)无限制(内核红黑树管理)
时间复杂度O(n)(每次遍历全部 fd)O(n)(遍历动态数组)O(1)(仅处理就绪事件)
数据拷贝方式全量拷贝 fd_set 到内核全量拷贝 pollfd 数组到内核共享内存(mmap 实现零拷贝)
触发模式仅水平触发(LT)仅水平触发(LT)支持 LT 和边缘触发(ET)
内核通知机制轮询检查所有 fd 状态轮询检查所有 fd 状态事件回调(就绪事件链表)
适用场景低并发(<1k)、跨平台中等并发(1k~10k)高并发(>10k)、Linux 平台、长连接低活跃场景
数据结构位图(fd_set动态数组(struct pollfd红黑树(注册 fd)+ 就绪链表(事件回调)
编程复杂度需手动重置 fd_set,易出错无需重置 fd,结构更灵活通过 epoll_ctl 动态管理 fd,接口简洁
性能瓶颈高并发时遍历效率低,内存拷贝开销大中等并发下可扩展,但拷贝和遍历仍为瓶颈高并发下高效,仅处理活跃 fd

2. 关键特性说明:

  1. 水平触发(LT)​:只要 fd 就绪,持续通知(如未读取完数据会反复触发)
  2. 边缘触发(ET)​:仅在状态变化时通知一次,需一次性处理完数据(适合高性能场景)
  3. 零拷贝:epoll 通过 mmap 共享内核与用户空间内存,避免重复数据拷贝
  4. 事件驱动:epoll 使用回调机制直接通知就绪事件,无需轮询所有

3. 应用场景

  • select:嵌入式设备、跨平台工具(旧版 FTP)
  • poll:传统 Web 服务器(早期 Apache)
  • epoll:Nginx、Redis、实时通信系统(直播平台)

2. 异步io

同步IO是指程序发起IO操作后,必须等待操作完成并获取结果后才能继续执行后续代码。整个过程会阻塞当前线程或进程
异步IO允许程序发起IO操作后立即返回,无需等待结果。内核在操作完成后通过回调、事件通知等方式告知程序,期间线程可执行其他任务

在这里插入图片描述

1. 频繁copy

内存共享 mmap

2. 如何做到线程安全

  1. 无锁队列:通过原子操作实现线程安全,适合高并发场景,但实现复杂。
  2. ​环形队列:通过循环缓冲区和同步机制实现线程安全,适合固定大小的队列场景。
  3. ​无锁环形队列:结合无锁编程和环形缓冲区的优点,提供高性能的线程安全队列。

3. io_uring

io_uring 是 Linux 内核提供的一种高效异步 I/O 框架,自 Linux 5.1 版本引入,旨在提升大规模并发 I/O 操作的性能,通过共享内存和环形缓冲区的方式,实现了高效的异步 I/O 操作
应用程序将 I/O 请求提交到 io_uring 的提交队列(SQ),内核异步处理这些请求,并将结果放入完成队列(CQ)。应用程序无需等待 I/O 操作完成,可以继续执行其他任务,之前仨本质还是同步io

  1. io_uring_setup
    io_uring_setup 是用于创建和初始化 io_uring 实例的系统调用。它的主要功能包括:

分配和配置提交队列(SQ)和完成队列(CQ)。
返回一个文件描述符(fd),用于标识 io_uring 实例。
支持通过 struct io_uring_params 参数配置额外的功能,如轮询模式(SQPOLL)或 I/O 轮询(IOPOLL)。

struct io_uring_params params;
int fd = io_uring_setup(entries, &params);
  1. io_uring_register
    io_uring_register 用于将文件描述符、缓冲区或其他资源预先注册到 io_uring 实例中。这样可以减少每次 I/O 操作时的开销,提高效率。常见的注册操作包括:注册文件描述符集合(IORING_REGISTER_FILES),注册内存缓冲区(IORING_REGISTER_BUFFERS),注册事件文件描述符(IORING_REGISTER_EVENTFD)
io_uring_register(fd, IORING_REGISTER_BUFFERS, buffers, buffer_count);
  1. io_uring_enter
    io_uring_enter 是用于提交和处理 I/O 操作的系统调用。它的主要功能包括:

将提交队列(SQ)中的 I/O 请求提交给内核。
等待完成队列(CQ)中的 I/O 操作结果。
支持批量提交和批量获取结果,减少系统调用次数。

io_uring_enter(fd, to_submit, min_complete, flags, NULL, 0);
  1. liburing库

1. 实现

#include <stdio.h>
#include <liburing.h>    // io_uring 异步IO库
#include <netinet/in.h>  // 套接字相关结构体
#include <string.h>      // memset/memcpy
#include <unistd.h>      // close/* 事件类型枚举 */
#define EVENT_ACCEPT   0  // 接受连接事件
#define EVENT_READ    1  // 读取数据事件
#define EVENT_WRITE   2  // 写入数据事件/* 连接信息结构体(存储于user_data) */
struct conn_info {int fd;     // 关联的文件描述符int event;  // 事件类型
};/* 初始化TCP服务器 */
int init_server(unsigned short port) {// 创建TCP套接字int sockfd = socket(AF_INET, SOCK_STREAM, 0);// 配置服务器地址struct sockaddr_in serveraddr;memset(&serveraddr, 0, sizeof(serveraddr));serveraddr.sin_family = AF_INET;serveraddr.sin_addr.s_addr = htonl(INADDR_ANY); // 监听所有接口serveraddr.sin_port = htons(port);              // 指定端口// 绑定地址if (bind(sockfd, (struct sockaddr*)&serveraddr, sizeof(serveraddr)) == -1) {perror("bind failed");return -1;}// 开始监听(等待队列长度10)listen(sockfd, 10);return sockfd;
}/* io_uring 参数 */
#define ENTRIES_LENGTH 1024  // 环队列大小
#define BUFFER_LENGTH  1024  // 读写缓冲区大小/* 设置接收事件到io_uring */
int set_event_recv(struct io_uring *ring, int sockfd, void *buf, size_t len, int flags) {// 获取提交队列项(SQE)struct io_uring_sqe *sqe = io_uring_get_sqe(ring);// 构造连接信息(存储到user_data)struct conn_info info = {.fd = sockfd,.event = EVENT_READ};// 准备RECV操作(异步接收数据)io_uring_prep_recv(sqe, sockfd, buf, len, flags);// 将连接信息存入user_data(用于后续识别事件)memcpy(&sqe->user_data, &info, sizeof(info));return 0;
}/* 设置发送事件到io_uring */
int set_event_send(struct io_uring *ring, int sockfd, void *buf, size_t len, int flags) {struct io_uring_sqe *sqe = io_uring_get_sqe(ring);struct conn_info info = {.fd = sockfd,.event = EVENT_WRITE};// 准备SEND操作(异步发送数据)io_uring_prep_send(sqe, sockfd, buf, len, flags);memcpy(&sqe->user_data, &info, sizeof(info));return 0;
}/* 设置接受连接事件到io_uring */
int set_event_accept(struct io_uring *ring, int sockfd, struct sockaddr *addr,socklen_t *addrlen, int flags) {struct io_uring_sqe *sqe = io_uring_get_sqe(ring);struct conn_info info = {.fd = sockfd,.event = EVENT_ACCEPT};// 准备ACCEPT操作(异步接受连接)io_uring_prep_accept(sqe, sockfd, addr, addrlen, flags);memcpy(&sqe->user_data, &info, sizeof(info));return 0;
}int main(int argc, char *argv[]) {// 初始化服务器套接字unsigned short port = 9999;int sockfd = init_server(port);// 初始化io_uring参数struct io_uring_params params;memset(&params, 0, sizeof(params));// 创建io_uring实例struct io_uring ring;io_uring_queue_init_params(ENTRIES_LENGTH, &ring, &params);// 准备接受连接的异步操作struct sockaddr_in clientaddr;socklen_t len = sizeof(clientaddr);set_event_accept(&ring, sockfd, (struct sockaddr*)&clientaddr, &len, 0);// 共享缓冲区(注意:多连接时存在竞争风险)char buffer[BUFFER_LENGTH] = {0};// 主事件循环while (1) {// 提交所有准备好的SQE到内核io_uring_submit(&ring);// 等待至少一个完成事件(阻塞等待)struct io_uring_cqe *cqe;io_uring_wait_cqe(&ring, &cqe);// 批量获取完成事件(最多128个)struct io_uring_cqe *cqes[128];int nready = io_uring_peek_batch_cqe(&ring, cqes, 128);//epoll_wait// 处理每个完成事件for (int i = 0; i < nready; i++) {struct io_uring_cqe *entry = cqes[i];struct conn_info result;memcpy(&result, &entry->user_data, sizeof(result));if (result.event == EVENT_ACCEPT) {// 处理新连接int connfd = entry->res; // accept返回的新fd// 重新注册ACCEPT事件(持续监听新连接)set_event_accept(&ring, sockfd, (struct sockaddr*)&clientaddr, &len, 0);// 注册新连接的读事件set_event_recv(&ring, connfd, buffer, BUFFER_LENGTH, 0);} else if (result.event == EVENT_READ) {// 处理读完成int ret = entry->res;if (ret <= 0) { // 连接关闭或错误close(result.fd);} else {        // 收到数据,准备回写set_event_send(&ring, result.fd, buffer, ret, 0);}} else if (result.event == EVENT_WRITE) {// 写完成,重新注册读事件set_event_recv(&ring, result.fd, buffer, BUFFER_LENGTH, 0);}}// 推进完成队列(标记已处理的事件)处理完就清空io_uring_cq_advance(&ring, nready);}
}
开始↓
初始化 TCP 服务器↓
初始化 io_uring 实例↓
注册 ACCEPT 事件到 io_uring↓
进入主事件循环↓
提交 I/O 请求到内核↓
等待完成事件↓
处理完成事件├── 如果是 ACCEPT 事件│     ↓│    接受新连接│     ↓│    重新注册 ACCEPT 事件│     ↓│    注册 READ 事件├── 如果是 READ 事件│     ↓│    读取数据│     ↓│    如果数据有效,注册 WRITE 事件│    否则关闭连接└── 如果是 WRITE 事件↓注册 READ 事件↓
推进完成队列↓
继续主事件循环

2. 关键点:

​异步衔接:每个操作完成后立即注册下一个操作(ACCEPT→READ→WRITE→READ循环)
​共享缓冲区:所有连接共用buffer变量,高并发时需改为连接独立缓冲区
​错误处理:当entry->res <= 0时直接关闭连接

3. 问题

1. Reactor 与 Proactor 的三点不同

Reactor 和 Proactor 是两种基于事件分发的网络编程模式,它们的核心区别在于事件处理流程和 I/O 操作的责任分配:

  1. ​事件处理流程

​Reactor:基于同步 I/O,主线程监听事件就绪后,由工作线程执行实际的 I/O 操作(如读/写)和业务处理。Reactor 感知的是「待完成」的 I/O 事件,应用程序需要主动调用系统调用(如 read/write)来获取数据。
​Proactor:基于异步 I/O,主线程直接处理 I/O 操作完成后的事件通知,工作线程仅处理业务逻辑。Proactor 感知的是「已完成」的 I/O 事件,操作系统负责完成数据搬运,应用程序只需处理准备好的数据。
2. ​I/O 操作责任

​Reactor:应用程序负责 I/O 调度和处理,需要主动调用系统调用来读取或写入数据,可能遇到部分读取/写入的情况,需自行管理缓冲区状态。
​Proactor:操作系统全权负责 I/O 操作,应用程序只需处理完成的事件,无需关注中间状态,内置错误处理机制。
3. ​平台实现

​Reactor:常见于 Linux 平台,典型实现包括 epoll 和 Java NIO。
​Proactor:常见于 Windows 平台,典型实现包括 IOCP(I/O 完成端口)和 Boost.Asio。

2. epoll 与 io_uring 的区别

epoll 和 io_uring 都是 Linux 中用于高效处理 I/O 操作的机制,但它们在设计思想和实现方式上有显著差异:

  1. ​设置与使用

epoll:设置好后,应用程序只需等待事件通知,无需频繁修改。epoll 通过事件驱动的方式,避免了频繁遍历文件描述符的性能开销,适合处理大量连接。
io_uring:每次 I/O 操作都需要通过提交队列(SQ)和完成队列(CQ)进行设置。应用程序需要将 I/O 请求放入提交队列,内核处理完成后将结果放入完成队列,应用程序再从完成队列中获取结果。

  1. ​设计思想

epoll:本质上是同步 I/O 的事件通知机制,应用程序在处理 I/O 事件时仍然需要进行实际的 I/O 操作,可能会导致线程阻塞。
io_uring:通过用户态和内核态共享提交队列和完成队列,减少了系统调用的次数和上下文切换的开销,支持真正的异步 I/O 操作,适合高并发场景。

  1. ​性能与灵活性
    epoll:适合处理大量连接,但在高并发场景下可能存在性能瓶颈。
    io_uring:通过批量提交和批量获取结果,减少了系统调用开销,支持多种 I/O 操作,具有更高的灵活性和扩展性

  2. 四种的对比
    select:简单但效率低,适合低并发或跨平台场景。
    poll:改进 select 的描述符数量限制,适合中等并发。
    epoll:事件驱动,适合高并发场景,是 Linux 下高性能服务的首选。
    io_uring:异步 I/O,性能最优,适合大规模高并发场景。

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

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

相关文章

【实战指南】基于DevExpress轻量化主题实现WPF应用性能升级

DevExpress WPF拥有120个控件和库&#xff0c;将帮助您交付满足甚至超出企业需求的高性能业务应用程序。通过DevExpress WPF能创建有着强大互动功能的XAML基础应用程序&#xff0c;这些应用程序专注于当代客户的需求和构建未来新一代支持触摸的解决方案。 无论是Office办公软件…

python-leetcode 56.电话号码的字母组合

题目&#xff1a; 给定一个仅包含数字的2-9的字符串&#xff0c;返回所有它可能表示的字母组合&#xff0c;答案可以按任意顺序返回 给出数字到字母的映射如下&#xff08;与电话按键相同&#xff09;&#xff0c;注意1不对应任何字母 方法一&#xff1a;深度优先搜索&#x…

5.0 VisionPro调用USB相机的方法与步骤说明(一)

本文介绍如何在C#中调用visionPro以处理USB相机采集到的图片。示例如下: 主要思路如下: 1. 使用AForge来打开以及采集usb相机照片。 usb相机处于一直运行状态。每隔100ms采集一次照片。且触发一次事件。 public void Start() { this.videoSourcePlayer.Stop(); …

论文阅读:Deep Hybrid Camera Deblurring for Smartphone Cameras

今天介绍一篇 ACM SIGGRAPH 2024 的文章&#xff0c;关于手机影像中的去模糊的文章。 Deep Hybrid Camera Deblurring for Smartphone Cameras Abstract 手机摄像头尽管取得了显著的进步&#xff0c;但由于传感器和镜头较为紧凑&#xff0c;在低光环境下的成像仍存在困难&am…

Linux中的基本指令(下)

目录 mv指令 more指令 less指令 head指令 tail 指令 继续理解文件 重定向和追加重定向操作 理解管道 find指令 whereis 指令 bc指令 uname ‒r指令 grep 指令 关机 扩展命令 zip/unzip 指令 tar指令 关于rzsz 系统间的文件互传 接上&#xff01; mv指令 m…

Unity WebGL IIS报错无法使用

Unity WebGL IIS报错无法使用 原因1&#xff1a;WebGL文件夹无访问权限 右键WebGL文件夹-属性 点击安全-编辑-添加 输入ever点击确定-应用即可

docker-compose install nginx(解决fastgpt跨区域)

CORS前言 CORS(Cross-Origin Resource Sharing,跨源资源共享)是一种安全措施,它允许或拒绝来自不同源(协议、域名、端口任一不同即为不同源)的网页访问另一源中的资源。它的主要作用如下: 同源策略限制:Web 浏览器的同源策略限制了从一个源加载的文档或脚本如何与另一…

vulnhub靶场之loly靶机

前言 挑战攻克该靶机30分钟 靶机&#xff1a;loly靶机&#xff0c;IP地址为192.168.10.11 攻击&#xff1a;kali&#xff0c;IP地址为192.168.10.6 靶机和攻击机都采用VMware虚拟机&#xff0c;都采用桥接网卡模式 文章涉及的靶机及工具&#xff0c;都可以自行访问官网或者项…

Deepseek API+Python测试用例一键生成与导出-V1.0.2【实现需求文档图片识别与用例生成自动化】

在测试工作中&#xff0c;需求文档中的图片&#xff08;如界面设计图、流程图&#xff09;往往是测试用例生成的重要参考。然而&#xff0c;手动提取图片并识别内容不仅耗时&#xff0c;还容易出错。本文将通过一个自研小工具&#xff0c;结合 PaddleOCR 和大模型&#xff0c;自…

Excel(函数篇):COUNTIF与CONUTIFS函数、SUMIF与SUMIFS函数、ROUND函数、MATCH与INDEX函数、混合引用与条件格式

目录 COUNTIF和COUNTIFS函数COUNTIF函数COUNTIFS函数SUMIF和SUMIFS函数SUMIF函数SUMIFS函数SUMIFS函数与控件实现动态年月汇总ROUND、ROUNDUP、ROUNDDOWN函数单元格混合引用条件格式与公式,标记整行数据MATCH和INDEX函数COUNTIF和COUNTIFS函数 COUNTIF函数 统计下“苏州”出现…

上位机数据可视化:使用QtCharts绘制波形图

工程配置 CMake文件 find_package(Qt5 COMPONENTS Charts REQUIRED)target_link_libraries(zhd-desktop PRIVATE Qt5::Charts)包含头文件以及名称空间&#xff08;这个很重要&#xff0c;没有包含名称空间编译器会提示找不到相关的类型&#xff09; #include <QtCharts&g…

CSS - Pseudo-classes(伪类选择器)

目录 一、介绍二、常用种类三、案例实现案例一&#xff1a;a标签使用link/visited/hover/active案例二&#xff1a;表单元素使用focus/disabled案例三、通过其余伪类实现元素灵活选中 一、介绍 CSS 伪类&#xff08;Pseudo-classes&#xff09; 用于定义元素的特定状态或结构位…

Ubuntu22.04虚拟机里安装Yolov8流程

1. 安装pytorch sudo apt install nvidia-cuda-toolkit nvcc --version # 官方适配地址&#xff1a;https://download.pytorch.org/whl/torch/import torch print(torch.__version__) print(torch.cuda.is_available())2. 安装环境 # cuDNN 安装&#xff1a;https://develop…

Spring 声明式事务管理

Spring 编程的方式实现事务管理&#xff0c;这样太过麻烦&#xff0c;需要在每个方法上面加上相应的事务处理操作&#xff0c;声明式事务处理能够很好的解决这个问题&#xff0c;比如通过tx命名空间&#xff0c;这样只需要配置就可以检测到相关的方法&#xff0c;或者是通过tra…

Chat2DB:让数据库管理像聊天一样简单

数据库工具的痛点与破局 在数据爆炸的时代&#xff0c;数据库管理工具已成为企业高效运营的刚需。然而&#xff0c;传统工具如Navicat、DBeaver虽功能强大&#xff0c;却让非技术人员和SQL新手望而却步。复杂的界面、繁琐的手动操作、晦涩的语法规则&#xff0c;成为横亘在数据…

Navicat for Snowflake 震撼首发,激活数据仓库管理全新动能

近日&#xff0c;Navicat 家族迎来了一位全新成员 — Navicat for Snowflake。Snowflake 是一款基于云架构的现代数据仓库解决方案&#xff0c;以其弹性扩展、高性能和易用性著称。这次首发的Navicat for Snowflake 专为简化 Snowflake 数据库管理任务而精心打造。它凭借其直观…

【项目合集】智能语音小车-微信小程序控制

功能需求&#xff1a; 车子检测环境温度、湿度&#xff0c;上报 APP、WEB 端显示实时数据可通过 APP 控制小车前进、左转、右转可通过语音控制小车前进后退车上一个 LED 灯&#xff0c;可通过 WEB、小程序控制在 APP、WEB 上均可注册登录 硬件清单 硬件 功能 备注 ESP32 …

人工智能与人的智能,改变一生的思维模型分享【4】决策树

决策树&#xff08; DECISION TREE&#xff09; 一般由一个决策图和若干可能的结果组成。是一种通过罗列解题的关键步骤以及各步骤发生的条件和结果&#xff0c;由此来创建到达目标的规划。 我们很早就知道有一个方法&#xff0c;叫做当你苦闷、纠结的时候&#xff0c;把你的所…

利用余弦相似度在大量文章中找出抄袭的文章

我前面的2篇文章分别讲了如果利用余弦相似度来判断2篇文章的相似度&#xff0c;来确定文章是否存在抄袭&#xff0c;和余弦相似度的原理&#xff0c;即余弦相似度到底是怎么来判断文章的相似性高低的等等。这一篇再说下&#xff0c;对于文章字数多和大量文章时&#xff0c;如果…

设计模式-对象创建

对象创建 前言1. Factory Method1.1 模式介绍1.2 模式代码1.2.1 问题代码1.2.2 重构代码 1.3 模式类图1.4 要点总结 2. Abstract Factory2.1 模式介绍2.2 模式代码2.2.1 问题代码2.2.2 重构代码 2.3 模式类图2.4 要点总结 3. Prototype3.1 模式介绍3.2 模式代码3.3 模式类图3.4…