当前位置: 首页 > news >正文

【Linux网络编程】多路转接IO(二)epoll

目录

epoll初识

epoll的相关系统调用

epoll的工作原理

 epoll的优点

epoll的工作方式

水平触发 Level Triggered 工作模式

边缘触发 Edge Triggered 工作模式

对比LT和ET

 理解 ET 模式和非阻塞文件描述符

epoll的惊群问题

基于LT模式的epoll代码样例


epoll初识

按照man手册的说法是为了处理大量句柄而做了改进的poll

Epoll 是 Linux 特有的高性能 I/O 多路复用机制,专为处理大量文件描述符设计,克服了 select/poll 的性能瓶颈。

epoll的相关系统调用

#include <sys/epoll.h>// 创建 epoll模型
int epoll_create(int size);// 控制 epoll 模型(增删改)
int epoll_ctl(int epfd, int op, int fd, struct epoll_event *event);// 等待事件
int epoll_wait(int epfd, struct epoll_event *events, int maxevents, int timeout);

(1)int epoll_create(int size); 

epoll_create的返回值是一个文件描述符,因此在使用完毕后,也要调用close进行关闭。

(2)int epoll_ctl(int epfd,int op, int fd, struct epoll_event*event);epoll事件注册函数。

  • 第一个参数是epoll_create的返回值(epoll句柄);
  • 第二个参数表示动作,增加,删除,修改;
  • 第三个参数是需要监听的文件描述符fd;
  • 第四个参数表示告诉内核要监听哪些事情;

第二个参数的取值:

  • EPOLL_CTL_ADD:注册新的 fd 到 epfd 中;
  • EPOLL_CTL_MOD:修改已经注册的 fd 的监听事件;
  • EPOLL_CTL_DEL:从 epfd 中删除一个 fd;

 第四个参数的类型:

重要的两个成员是events表示要关心的事件,还有一个fd表示文件描述符。 

其中events表示要关心的事件,使用以下宏来表示:

  • EPOLLIN : 表示对应的文件描述符可以读 (包括对端 SOCKET 正常关闭);
  • EPOLLOUT : 表示对应的文件描述符可以写;
  • EPOLLPRI : 表示对应的文件描述符有紧急的数据可读 (这里应该表示有带外数据到来);
  • EPOLLERR : 表示对应的文件描述符发生错误;
  • EPOLLHUP : 表示对应的文件描述符被挂断;
  • EPOLLET : 将 EPOLL 设为边缘触发(Edge Triggered)模式, 这是相对于水平触发(Level Triggered)来说的;
  • EPOLLONESHOT:只监听一次事件, 当监听完这次事件之后, 如果还需要继续监听这个 socket 的话, 需要再次把这个 socket 加入到 EPOLL 队列里。 

 (3)int epoll_wait(int epfd, struct epoll_event * events, int maxevents, int timeout);

参数events是输出型参数,就绪的文件描述符和事件通过这个参数给我们返回。

maxevents 告之内核这个 events 有多大,这个 maxevents 的值不能大于创建epoll_create()时的 size

参数 timeout 是超时时间 (毫秒,0 会立即返回,-1 是永久阻塞)。

如果函数调用成功,返回对应 I/O 上已准备好的文件描述符数目,如返回 0 表示已超时, 返回小于 0 表示函数失败。

epoll的工作原理

首先当我们调用epoll_create创建一个epoll模型时,内核会为我们创建一颗红黑树。使用这颗红黑树来管理文件描述符和其对应要关心的事件。

红黑树传送门:【C++篇】红黑树的实现_红黑树代码实现-CSDN博客

同时内核还会维护一个就绪队列,当某个或几个文件描述符就绪时,就会将对应的节点链入到就绪队列中,同时通知上层,将 就绪的文件描述符通知给上层。

在网络协议栈中,存在一种回调机制:当底层特定的文件描述符上有数据时,会自动进行回调,找到对应的红黑树节点,并将该节点链入到就绪队列中,这个过程的事件复杂度是O(1)的

可以总结为如下图所示:

 epoll_ctl就是对这颗红黑树进行增删改,而epoll_wait就是从就绪队列中获取就绪的文件描述符。

关于就绪队列,其本质就是一个基于事件就绪的生产者消费者模型,当有事件就绪时,就会通知上层将事件拿走,如果没有事件就绪时(就绪队列为空),就会等待timeout的时间。

当我们调用epoll_wait 获取就绪的事件时,需要我们传入一个struct epoll_event的数组,内核会依次拷贝就绪队列中的事件到我们传入的数组events中,下标从0开始。同时epoll_wait的返回值表示事件就绪的个数。因此,在应用层处理事件就绪的时候,一般不需要非法检测。

还有,epoll接口是线程安全的,其内部已经加锁了。

细节点:当我们调用epoll_ctl向底层的红黑树中插入节点的时候,还会向底层注册一个回调方法,当该文件描述符就绪的时候,会立即找到对应的红黑树节点,然后将该节点链入到就绪队列中。

 epoll的优点

接口使用方便:虽然拆分成了三个函数,但是反而使用起来更方便高效。不需要每次循环都设置关注的文件描述符,也做到了输入输出参数分离开。相当于弥补了select的缺点。

数据拷贝轻量: 只在合适的时候调用 EPOLL_CTL_ADD 将文件描述符结构拷贝到内核中, 这个操作并不频繁(而 select/poll 都是每次循环都要进行拷贝)

事件回调机制:避免使用遍历,而是使用回调函数的方式,将就绪的文件描述符结构加入到就绪队列中,epoll_wait 返回直接访问就绪队列就知道哪些文件描述符就绪。这个操作时间复杂度 O(1)。即使文件描述符数目很多,效率也不会受到影响。

没有数量限制:文件描述符数目无上限。

epoll的工作方式

epoll 有 2 种工作方式:水平触发(LT)和边缘触发(ET)

水平触发 Level Triggered 工作模式

当 epoll 检测到 socket 上事件就绪的时候,可以不立刻进行处理,或者只处理一部分。

在第二次调用epoll_wait 时,epoll_wait 仍然会立刻返回并通知 socket 读事件就绪。

直到缓冲区上所有的数据都被处理完,epoll_wait 才不会立刻返回。

支持阻塞读写和非阻塞读写。

边缘触发 Edge Triggered 工作模式

当 epoll 检测到 socket 上事件就绪时, 必须立刻处理。

也就是说, ET 模式下, 文件描述符上的事件就绪后, 只有一次处理机会。

使用ET的工作方式,就要求我们必须把缓冲区中的数据读完,所以我们上层在调用read的时候,必须循环读取,但是我们不知道什么时候读完,所以可能会出现数据读完了,循环再次调用read,但此时缓冲区中的数据为空,这时程序就会阻塞在read这里,直到缓冲区中有数据了。

所以使用ET的工作方式,必须支持非阻塞的读写。当数据读取完后,全局的错误码errno会被设置为EAGAIN或EWOULDBLOCK。所以我们可以根据错误码,判断是否读取完数据。

ET 的性能比 LT 性能更高( epoll_wait 返回的次数少了很多)。

select 和 poll 其实也是工作在 LT 模式下。epoll 既可以支持 LT,也可以支持 ET。

对比LT和ET

LT 是 epoll 的默认行为。
使用 ET 能够减少 epoll 触发的次数。但是代价就是强逼着程序猿一次响应就绪过程中就把所有的数据都处理完。

相当于一个文件描述符就绪之后, 不会反复被提示就绪, 看起来就比 LT 更高效一些。但是在 LT 情况下如果也能做到每次就绪的文件描述符都立刻处理, 不让这个就绪被重复提示的话,其实性能也是一样的。另一方面,ET 的代码复杂程度更高了。

 理解 ET 模式和非阻塞文件描述符

使用 ET 模式的 epoll,需要将文件描述设置为非阻塞。这个不是接口上的要求,而是 "工程实践" 上的要求

假设这样的场景:服务器接收到一个 10k 的请求,会向客户端返回一个应答数据。如果客户端收不到应答,不会发送第二个 10k 请求。

如果服务端写的代码是阻塞式的 read,并且一次只 read 1k 数据的话(read 不能保证一次就把所有的数据都读出来,参考 man 手册的说明,可能被信号打断),剩下的 9k 数据就会待在缓冲区中。 

 

此时由于 epoll 是 ET 模式,并不会认为文件描述符读就绪。epoll_wait 就不会再次返回。剩下的 9k 数据会一直在缓冲区中。直到下一次客户端再给服务器写数据,epoll_wait 才能返回。

但是问题来了:

  1. 服务器只读到 1k 个数据,要 10k 读完才会给客户端返回响应数据。
  2. 客户端要读到服务器的响应, 才会发送下一个请求。
  3. 客户端发送了下一个请求,epoll_wait 才会返回,才能去读缓冲区中剩余的数据。 

 

所以, 为了解决上述问题(阻塞 read 不一定能一下把完整的请求读完), 于是就可以使用非阻塞轮询的方式来读缓冲区,保证一定能把完整的请求都读出来。 

而如果是 LT 没这个问题。只要缓冲区中的数据没读完,就能够让 epoll_wait 返回文件描述符读就绪。

epoll的惊群问题

惊群问题是指在多进程/多线程中,当多个进程/线程同时等待同一个事件(如一个socket连接),当该事件发生时,所有的进程/线程被唤醒,但最终只有一个进程/线程能成功处理该事件,而其他进程/线程被唤醒后发现无事可做,造成资源浪费的现象。

在epoll中,惊群问题主要出现在以下场景:

         多进程共享同一个监听socket:多个进程(例如通过fork创建的子进程)共享同一个监听套接字,并且每个进程都使用epoll_wait来等待该套接字上的连接事件(EPOLLIN)。当一个新的连接到来时,所有进程的epoll_wait都会被唤醒,但只有一个进程能够成功调用accept获取这个连接,其他进程的accept将返回EAGAIN或EWOULDBLOCK错误(在非阻塞模式下)或者阻塞(在阻塞模式下),这导致不必要的上下文切换和资源浪费。

多线程下的解决方案:

这种情况,不建议让多个线程同时在epoll_wait监听的socket,而是让其中一个线程epoll_wait监听的socket,当有新的链接请求进来之后,由epoll_wait的线程调用accept,建立新的连接,然后交给其他工作线程处理后续的数据读写请求,这样就可以避免了由于多线程环境下的epoll_wait惊群效应问题。

多进程下的解决方案:

在多个进程中使用一个共享锁,在调用accept之前先获取锁,这样只有一个进程能够进入accept。但是这样会导致其他进程在锁上阻塞,而且锁的竞争也会带来开销,因此不推荐。

在Linux 4.5及以后的内核中,可以在epoll_ctl添加监听套接字时,在events中设置EPOLLEXCLUSIVE标志。这样,当一个新的连接到来时,内核只会唤醒一个等待在epoll_wait上的进程(或线程),从而避免惊群。

基于LT模式的epoll代码样例

仓库连接:Epoll_Server · 小鬼/linux学习 - 码云 - 开源中国

相关文章:

【Linux网络编程】多路转接IO(二)epoll

目录 epoll初识 epoll的相关系统调用 epoll的工作原理 epoll的优点 epoll的工作方式 水平触发 Level Triggered 工作模式 边缘触发 Edge Triggered 工作模式 对比LT和ET 理解 ET 模式和非阻塞文件描述符 epoll的惊群问题 基于LT模式的epoll代码样例 epoll初识 按照man…...

flutter的包管理#资源管理#调试Flutter应用#Flutter异常捕获

2.5 包管理 2.5.1 简介 在软件开发中&#xff0c;很多时候有一些公共的库或 SDK 可能会被很多项目用到&#xff0c;因此&#xff0c;将这些代码单独抽到一个独立模块&#xff0c;然后哪个项目需要使用时再直接集成这个模块&#xff0c;便可大大提高开发效率。很多编程语言或开…...

Unity Netcode自定义数据传输——结构体及其序列化

在 Unity Netcode 中&#xff0c;要实现自定义数据的网络传输&#xff0c;确实需要两个关键部分&#xff1a; ✅ 两个必需组件&#xff1a; 数据结构定义 public struct PlayerState : INetworkSerializable {public int id; // 字段1&#xff1a;玩家IDpublic bool …...

Vue 3 高级编程技巧

Vue 3 高级编程技巧 1. 计算属性 (Computed Properties) 含义&#xff1a;计算属性在依赖变化时会自动更新。以下是一个示例&#xff0c;展示当 firstName 或 lastName 变化时&#xff0c;fullName 也会更新。 实例&#xff1a; <script setup> import { ref, comput…...

GraphQL注入 -- GPN CTF 2025 Real Christmas

part 1 服务器会每段时间禁用已注册的账号,此处存在漏洞 def deactivate_user_graphql(email):graphql_endpoint current_app.config["GRAPHQL_ENDPOINT"]query f"""mutation {{deactivateUser (user: {{email: "{email}"}}){{ success…...

python打卡day43

疏锦行 作业&#xff1a; kaggle找到一个图像数据集&#xff0c;用cnn网络进行训练并且用grad-cam做可视化 进阶&#xff1a;并拆分成多个文件 import torch import torch.nn as nn import torch.optim as optim from torchvision import datasets, transforms# 数据预处理 tra…...

ethers.js express vue2 定时任务每天凌晨2点监听合约地址数据同步到Mysql整理

下面是一个完整的 Ethers.js Express Vue2 MySQL 实现方案&#xff0c;用于&#xff1a; &#x1f4a1;每天凌晨 2 点监听某合约地址的 Transfer 事件&#xff0c;写入 MySQL 数据库&#xff0c;并展示每日 NFT 交易量图表&#xff08;Vue2 ECharts&#xff09; ✅ 后端部分…...

内网穿透和端口映射的区别在哪?局域网提供互联网访问方案对比选择详解

内网穿透和端口映射是两个经常被提及的概念&#xff0c;它们对于实现网络中的内外网通信起着关键作用。内网穿透和端口映射都能够有效地将本地局域网地址提供给互联网上外网访问&#xff0c;但二者之间存在着显著的区别。 内网穿透与端口映射的核心区别在于实现方式和依赖条件…...

机器学习---正则化、过拟合抑制与特征筛选

专栏:机器学习 个人主页:云端筑梦狮 注&#xff1a;上一篇机器学习还差一小节&#xff0c;日后坑必会填上 一.正则化 什么是正则化 / 如何进行正则化 其实机器学习中正则化&#xff08;regularization&#xff09;的外在形式非常简单&#xff0c;就是在模型的损失函数中加…...

优化 ArcPy 脚本性能

合理设置环境变量 优化环境变量配置 ArcPy 提供了许多环境变量&#xff0c;用于控制地理处理工具的行为。合理设置环境变量可以优化脚本的性能。例如&#xff0c;设置“workspace”环境变量可以指定默认的工作空间&#xff0c;避免在脚本中重复指定工作空间路径。 Python 复制…...

Robyn高性能Web框架系列06:使用WebSocket实现产品智能助理

使用WebSocket实现产品智能助理 WebSocket原理与应用场景Robyn的WebSocket基本使用1、创建WebSocket服务2、侦听WebSocket事件3、向客户端发送消息4、向客户端广播消息5、使用查询参数6、主动关闭连接 示例&#xff1a;简易的产品智能助理1、产品数据部分2、产品信息部分3、智能…...

UDP 缓冲区

UDP 有接收缓冲区&#xff0c;没有发送缓冲区 引申问题 1、为什么没有发送缓冲区&#xff1f; 直接引用原文 “因为 UDP 是不可靠的&#xff0c;它不必保存应用进程的数据拷贝&#xff0c;因此无需一个真正的发送缓冲区” 2、没有发送缓冲区的情况下&#xff0c;sendto 的数…...

物联网与低代码:Node-RED如何赋能工业智能化与纵横智控的创新实践

在数字化浪潮席卷全球的今天&#xff0c;物联网&#xff08;IoT&#xff09;已从概念走向现实&#xff0c;成为连接物理世界与数字世界的关键桥梁。它通过将日常物品、工业设备等“物”嵌入传感器、软件及其他技术&#xff0c;使其能够通过网络相互连接并交换数据&#xff0c;从…...

【甲方安全视角】开源的安全悖论

文章目录 安全的充分必要条件&#xff1a;从「符号化信任」到「验证驱动安全」构建与分发的不可信链条迭代与审计的节奏错位代码透明与攻击面的对等暴露对普通用户的建议选择可信项目与品牌始终通过官方渠道获取软件注意权限与环境安全对“签名请求”、“连接钱包”等敏感操作保…...

GEO生成式引擎优化发展迅猛:热点数智化传播是GEO最佳路径

在人工智能技术浪潮的推动下&#xff0c;GEO生成式引擎优化已跃升为行业技术演进与产业发展相融合的核心赛道。通过系统性梳理其发展脉络&#xff0c;我们可清晰勾勒出技术突破与产业变革交织的演进轨迹&#xff0c;其发展进程包含以下重要节点。 2023年4月&#xff0c;GPT-4发…...

【unity游戏开发——网络】计算机网络中的三种数据管理模型(分散式、集中式、分布式)和三大通信模型(C/S、B/S、P2P)

注意&#xff1a;考虑到热更新的内容比较多&#xff0c;我将热更新的内容分开&#xff0c;并全部整合放在【unity游戏开发——网络】专栏里&#xff0c;感兴趣的小伙伴可以前往逐一查看学习。 文章目录 一、数据管理模型1、分散式 (Decentralized - 各管各的)2、集中式 (Centra…...

MR30分布式 IO在物流堆垛机的应用

在现代物流行业蓬勃发展的浪潮中&#xff0c;物流堆垛机作为自动化仓储系统的核心设备&#xff0c;承担着货物的高效存取与搬运任务。它凭借自动化操作、高精度定位等优势&#xff0c;极大地提升了仓储空间利用率和货物周转效率。然而&#xff0c;随着物流行业的高速发展&#…...

香港维尔利健康科技集团推出AI辅助医学影像训练平台,助力医护人才数字化转型

香港维尔利健康科技集团近日正式发布其自主研发的“AI辅助医学影像训练平台&#xff08;V-MedTrain&#xff09;”&#xff0c;这一创新平台的上线&#xff0c;标志着医学影像教育迈入智能化辅助教学新时代。依托人工智能与大数据分析技术&#xff0c;香港维尔利健康科技集团在…...

2025学年湖北省职业院校技能大赛 “信息安全管理与评估”赛项 样题卷(五)

2025学年湖北省职业院校技能大赛 “信息安全管理与评估”赛项 样题卷&#xff08;五&#xff09; 第二部分&#xff1a;网络安全事件响应、数字取证调查、应用程序安全任务书任务 1&#xff1a;应急响应&#xff08;可以培训有答案&#xff09;任务 2&#xff1a;通信数据分析取…...

基于 Python 的批量文件重命名软件设计与实现

在工作过程中,经常有很多文件,想要对文件名进行批量改名,特此写了一个程序,以实现此功能。 一、批量文件重命名软件设计原理 (一)核心原理阐述 批量文件重命名软件的核心原理在于运用操作系统提供的文件管理功能,借助编程手段达成对文件名称的批量修改。在这个软件里,…...

【深度学习新浪潮】什么是上下文工程?

什么是上下文工程? 上下文工程(Context Engineering) 是指通过设计、优化与大语言模型(LLM)交互时的输入内容(即“上下文”),引导模型生成更符合预期、更精准回答的系统性方法。这里的“上下文”通常包括 提示词(Prompt)、示例(Few-Shot Examples)、历史对话记录、…...

逆向入门(8)汇编篇-rol指令的学习

还是那个题&#xff0c;这回又碰到个循环左移&#xff0c;有挺多操作方法之前都没有系统的学&#xff0c;用到的时候再看看感觉还挺好&#xff0c;不耽误事 0x00 基本介绍 ROL(Rotate Left): 循环左移&#xff0c;它有两个操作数&#xff1a; 第一个操作数是目标操作数&#…...

Fisco Bcos学习 - 开发第一个区块链应用

文章目录 一、前言二、业务场景分析&#xff1a;简易资产管理系统三、智能合约设计与实现3.1 存储结构设计3.2 接口设计3.3 完整合约代码 四、合约编译与Java接口生成五、SDK配置与项目搭建5.1 获取Java工程项目5.2 项目目录结构5.3 引入Web3SDK5.4 证书与配置文件 六、业务开发…...

黑马python(十六)

目录&#xff1a; 1.JSON数据格式的转换 2.pyecharts模块简介 3.pyecharts入门使用 4.数据准备 5.生成折线图 1.JSON数据格式的转换 2.pyecharts模块简介 官方网站&#xff1a; 画廊网站:有更多的图标形式 测试是否安装 3.pyecharts入门使用 运行会生成一个html的文件&a…...

完成国产化替代!昆明卷烟厂用时序数据库 TDengine 重塑工业时序数据平台

小T导读&#xff1a;昆明卷烟厂作为红云红河烟草&#xff08;集团&#xff09;有限责任公司的重要组成部分&#xff0c;是集团卷烟生产的核心工厂。早期在建设制造执行系统&#xff08;MES&#xff09;时&#xff0c;其采用了 Wonderware 平台的时序数据存储功能模块&#xff0…...

50天50个小项目 (Vue3 + Tailwindcss V4) ✨ | BackgroundSlider(背景滑块)

&#x1f4c5; 我们继续 50 个小项目挑战&#xff01;—— BackgroundSlider组件 仓库地址&#xff1a;https://github.com/SunACong/50-vue-projects 项目预览地址&#xff1a;https://50-vue-projects.vercel.app/ 使用 Vue 3 的 Composition API 和 <script setup> …...

Wpf的Binding

前言 wpf的Binding就像一个桥梁&#xff0c;它的作用就是连接逻辑层与界面层&#xff0c;既能够把逻辑层的数据搬到界面层展示&#xff0c;又能将界面层的数据更改后传递到逻辑层&#xff0c;Binding的数据来源就是Binding的源&#xff0c;数据展示的地方就是Binding的目标。 …...

Redis—持久化

持久化 在mysql当中&#xff0c;有4个比较关心的特性&#xff0c;分别是原子性、一致性、隔离性和持久性。这里的持久性和持久化是一回事。我们该如何判断是否具有持久性呢&#xff1f;答案就是看重启进程或者主机之后&#xff0c;数据是否存在。当我们把数据存储在硬盘上是就…...

Spring Boot中日志管理与异常处理

以下是Spring Boot中日志管理与异常处理的系统化实践指南&#xff0c;结合最佳实践与核心配置&#xff0c;确保应用健壮性与可维护性。 &#x1f4ca; 一、日志管理核心配置 默认框架与级别控制 Logback 是Spring Boot默认日志框架&#xff0c;通过application.yml快速配置&…...

基于MATLAB的BP神经网络的心电图分类方法应用

说明&#xff1a;这是一个机器学习实战项目&#xff08;附带数据代码文档&#xff09;&#xff0c;如需数据代码文档可以直接到文章最后关注获取。 1.项目背景 心电图&#xff08;ECG&#xff09;是临床诊断心血管疾病的重要工具&#xff0c;能够反映心脏电活动的周期性变化。…...

【笔记】Docker 配置阿里云镜像加速(公共地址即开即用,无需手动创建实例)

2025年06月25日记 【好用但慎用】Windows 系统中将所有 WSL 发行版从 C 盘迁移到 非系统 盘的完整笔记&#xff08;附 异常处理&#xff09;-CSDN博客 【笔记】解决 WSL 迁移后 Docker 出现 “starting services: initializing Docker API Proxy: setting up docker ap” 问题…...

Java 中LinkedList 总结

406.根据身高重建队列 力扣题目链接(opens new window) 假设有打乱顺序的一群人站成一个队列&#xff0c;数组 people 表示队列中一些人的属性&#xff08;不一定按顺序&#xff09;。每个 people[i] [hi, ki] 表示第 i 个人的身高为 hi &#xff0c;前面 正好 有 ki 个身高…...

微信小程序 / UNIAPP --- 阻止小程序返回(顶部导航栏返回、左 / 右滑手势、安卓物理返回键和调用 navigateBack 接口)

目录 理解page-container的原理 设置禁止点击遮盖层关闭&#xff1f; 阻止左滑返回 理解page-container的原理 page-container组件的所有属性&#xff0c;最重要的是show值。在页面上引入这个组件后&#xff0c;若show值为true&#xff0c;页面上所有各种方式触发的返回操作…...

Linux基本指令篇 —— mv指令

在Windows中我们经常使用CtrlX和CtrlV将一个地方的文件或目录移动到另一个地方&#xff0c;我们若是要在Linux当中完成此操作&#xff0c;则需要使用mv指令。mv 是 Linux 系统中用于移动或重命名文件和目录的基本命令之一&#xff0c;是 "move" 的缩写。下面将详细介…...

基于STM32的智能节能风扇的设计

基于STM32的智能节能风扇的设计 内容:1.摘要 本设计旨在解决传统风扇能耗高、功能单一的问题&#xff0c;提出一种基于STM32的智能节能风扇。通过结合温度传感器、人体红外传感器等多种传感器&#xff0c;利用STM32微控制器实现对风扇的智能控制。经过实际测试&#xff0c;该智…...

HCIA-IP路由基础

前言&#xff1a;本博客仅作记录学习使用&#xff0c;部分图片出自网络&#xff0c;如有侵犯您的权益&#xff0c;请联系删除 ​ 本篇笔记是根据B站上的视频教程整理而成&#xff0c;感谢UP主的精彩讲解&#xff01;如果需要了解更多细节&#xff0c;可以参考以下视频&#xf…...

Linux 内存管理之page cache

文章目录 一、page cache1.1 File-backed pages和Anonymous pages1.2 page cache/slab cache1.3 读/写路径1.4 脏页回写1.5 drop_caches1.6 时间局部性与空间局部性1.7 Page Cache 的两种类型1.8 关键数据结构 二、Page Cache 的产生2.1 Buffered I/O&#xff08;标准 I/O&…...

uniApp实战四:网络请求封装

文章目录 1.最终效果预览2.请求封装3.创建config配置文件4.创建api请求5.页面调用 说明&#xff1a;当前笔记基于Vue3开发&#xff0c;HbuilderX版本4.66 1.最终效果预览 2.请求封装 在util/request.js下创建js文件&#xff0c;代码如下 import config from /configconst tim…...

sentinel 自定义 dashboard 用户名密码

默认情况下&#xff0c;sentinel dashboard 用户名密码为 sentinel / sentinel &#xff0c;这里我使用重写 镜像的方式&#xff1a; // 定义 Dockerfile $ cat Dockerfile # 基于现有 Sentinel Dashboard 镜像 FROM bladex/sentinel-dashboard:1.8.4# 重新定义 ENTRYPOINT&…...

Fisco Bcos学习 - 搭建星形拓扑组网

文章目录 一、前言二、环境准备与依赖安装2.1 系统要求2.2 依赖安装 三、星形拓扑设计与节点规划四、使用build_chain.sh构建星形拓扑4.1 创建操作目录并获取脚本4.2 生成星形拓扑配置文件4.3 执行构建命令4.4 查看生成的节点文件 五、启动节点与共识验证5.1 启动所有节点5.2 查…...

深度学习入门--(二)感知机

一.感知机是什么 简单的输入和输出&#xff0c;感觉&#xff08;输入&#xff09;&#xff0c;知道&#xff08;输出&#xff0c;作出反应&#xff09; 二.简单逻辑电路 2.1与门 import numpy as np #AND def AND(X1,X2):w1,w2,thera0.5,0.5,0.7tmpX1*w1X2*w2if tmp>the…...

LeetCode 3298.统计重新排列后包含另一个字符串的子字符串数目2

给你两个字符串 word1 和 word2 。 如果一个字符串 x 重新排列后&#xff0c;word2 是重排字符串的 前缀 &#xff0c;那么我们称字符串 x 是 合法的 。 请你返回 word1 中 合法 子字符串 的数目。 注意 &#xff0c;这个问题中的内存限制比其他题目要 小 &#xff0c;所以你…...

【nRF52832】【环境搭建 1】【ubuntu下搭建nRF52832开发环境】

本文讲述如何在 ubuntu 22.04 下开发 nRF52832. host 环境说明: $ uname -a Linux leo 6.8.0-60-generic #63~22.04.1-Ubuntu SMP PREEMPT_DYNAMIC Tue Apr 22 19:00:15 UTC 2 x86_64 x86_64 x86_64 GNU/Linux1. 安装软件 sudo apt install gcc-arm-none-eabisudo apt-get i…...

Django

1. Django 和 Tornado 的关系 Django 是一个高级 Python Web 框架&#xff0c;它鼓励快速开发和干净、实用的设计。Django 遵循 MVC&#xff08;模型-视图-控制器&#xff09;设计模式的一个变种&#xff0c;称为 MTV&#xff08;模型-模板-视图&#xff09;。Django 框架提供…...

51c嵌入式~CAN~合集2

我自己的原文哦~ https://blog.51cto.com/whaosoft/14016935 一、CAN总线常见信号干扰问题 定位干扰原因 当总线有干扰时&#xff0c;有经验的工程师能够迅速定位&#xff0c;但是对于新手来说却很麻烦。 造成总线干扰的原因有很多&#xff0c;比如通过电磁辐射耦合到通…...

【iOS】iOS崩溃总结

【iOS】iOS崩溃总结 一、前言 之前写了一篇博文《【Flutter】程序报错导致的灰屏总结》&#xff0c;浏览量、收藏率和点赞量还挺高&#xff0c;还被收录了&#xff0c;就想着总结一下iOS崩溃&#xff0c;这个也是在iOS面试中经常被问到的。 在 iOS 开发过程中&#xff0c;导致…...

npm 报错:“无法加载文件 ...npm.ps1,因为在此系统上禁止运行脚本” 解决方案(附执行策略说明)

在使用 npm 命令时&#xff0c;部分 Windows 用户可能会遇到如下错误&#xff1a; npm : 无法加载文件 D:\nvm4w\nodejs\npm.ps1&#xff0c;因为在此系统上禁止运行脚本。有关详细信息&#xff0c;请参阅 https://go.microsoft.com/fwlink/?LinkID135170 中的 about_Executi…...

AES加密:为你的PDF文档加上一道钢铁防线

在数字化时代&#xff0c;确保敏感数据的安全性至关重要。加密技术在保护信息免受未经授权访问方面起着关键作用。而在众多加密标准中&#xff0c;AES&#xff08;高级加密标准&#xff09;因其强大的安全性和广泛的应用而脱颖而出。那么&#xff0c;AES加密如何应用到PDF文档中…...

2025学年湖北省职业院校技能大赛 “信息安全管理与评估”赛项 样题卷(一)

2025学年湖北省职业院校技能大赛 “信息安全管理与评估”赛项 样题卷&#xff08;一&#xff09; 第一部分&#xff1a;网络平台搭建与设备安全防护任务书DCRS:DCFW:DCWS:WAF: 第二部分&#xff1a;网络安全事件响应、数字取证调查、应用程序安全任务书任务 1&#xff1a;应急响…...

1688商品发布API:自动化上架与信息同步

一、1688商品发布API的核心功能与技术架构 1.1 API功能全景 1688商品发布API是1688开放平台的核心组件之一&#xff0c;支持商品信息的自动化发布、编辑、上下架及库存同步。其核心功能包括&#xff1a; 商品信息管理&#xff1a;支持商品标题、描述、价格、库存、SKU&#…...