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

Linux epoll 详解:概念、使用、数据结构、流程及应用

epoll是什么?

epoll 是从 Linux 2.6 起,Linux内核提供的一种高性能I/O事件通知机制,用于解决传统 select 和 poll 在处理大量并发连接时遍历、最大数量限制、频繁拷贝数据等问题。epoll 可以用来监听多个文件描述符(socket、管道、eventfd、timerfd 等)上的I/O事件。

核心特点

  • 高效的事件驱动模型

    • O(1) 时间复杂度:不管监控多少文件描述符(FD),epoll 的事件检测效率几乎不变,而 select/poll 是 O(n) 的。
    • 仅返回活跃的 FD:不像 select/poll 需要遍历所有 FD,epoll 只返回有事件发生的 FD,减少无效遍历。
  • 支持大并发连接

    • 单进程可轻松管理 数十万甚至百万级 的并发连接(如 Nginx、Redis 使用 epoll 实现高并发)。

    • 使用 红黑树(RB-tree)存储 FD,查找、插入、删除高效。

  • 边缘触发(ET)和水平触发(LT)模式

    • 水平触发(LT,默认模式):只要 FD 可读/可写,epoll 会一直通知应用程序(类似 poll)。
    • 边缘触发(ET):仅在 FD 状态变化时通知一次(更高效,但需正确处理,否则可能丢失事件)。

epoll 怎么用?

epoll_create

int epoll_create(int size);

作用:创建 epoll 实例,得到 epoll 文件描述符,用于后续对 epoll 的所有调用。

当不在需要时调用 close() 关闭,当所有引用 epoll 实例的文件描述符都关闭后,内核将销毁该实例并释放相关资源以供重用。

返回值:成功时,返回文件描述符;错误时,返回 -1,并设置 errno。

epoll_ctl

int epoll_ctl(int epfd, int op, int fd, struct epoll_event *event);

作用:添加/修改/删除要监听的 fd;通过对文件描述符 epfd 引用的 epoll 实例执行控制操作,对目标文件描述符 fd 执行 op

event 参数描述了链接到文件描述符 fd 的对象。

op 参数

op功能说明
EPOLL_CTL_ADD添加新 fd 到 epoll 实例已存在返回 EEXIST
EPOLL_CTL_MOD修改 fd 的监听事件不存在返回 ENOENT
EPOLL_CTL_DEL从 epoll 实例中移除 fdevent 参数可以是 NULL

事件

// eventpoll.h
#define EPOLLIN     (__force __poll_t)0x00000001
#define EPOLLOUT    (__force __poll_t)0x00000004
#define EPOLLERR    (__force __poll_t)0x00000008
#define EPOLLHUP    (__force __poll_t)0x00000010
#define EPOLLRDHUP  (__force __poll_t)0x00002000
#define EPOLLEXCLUSIVE  ((__force __poll_t)(1U << 28))
#define EPOLLET     ((__force __poll_t)(1U << 31))

struct epoll_event 定义如下:

typedef union epoll_data {void        *ptr;int          fd;uint32_t     u32;uint64_t     u64;
} epoll_data_t;struct epoll_event {uint32_t     events;      /* Epoll events */epoll_data_t data;        /* User data variable */
};

epoll 的事件类型,就是在 epoll_event.events 里设置的,epoll 会根据这些事件类型来判断是否要把 fd 加入活跃队列,最后由 epoll_wait() 返回。

宏定义含义
EPOLLIN表示对应的文件描述符可以读(recv/read)
EPOLLOUT表示对应的文件描述符可以写(send/write)
EPOLLRDHUP表示对方关闭了写端或者半关闭(对 TCP 非常有用)
EPOLLERR表示对应的文件描述符发生错误
EPOLLHUP表示对应的文件描述符被挂断(对方断开连接)
EPOLLET边缘触发(Edge Trigger)
EPOLLONESHOT事件只触发一次,触发后自动从 epoll 中移除

返回值:成功时,返回文件描述符;错误时,返回 -1,并设置 errno。

epoll_wait

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

作用:等待文件描述符 epfd 指向的 epoll 实例上的事件 。events 指向的内存区域将包含调用者可用的事件。epoll_wait () 最多返回 maxevents 个事件。 maxevents 参数必须大于零。

timeout 参数指定 epoll_wait() 阻塞的最小毫秒数。将超时指定为 -1 会导致 epoll_wait() 无限期阻塞,同时指定等于零的超时会导致 epoll_wait () 立即返回,即使没有可用事件。

返回值:成功时,返回已为就绪的 I/O 文件描述符数量;如果在请求的超时毫秒数内没有文件描述符就绪,则返回0;错误时,返回 -1,并设置 errno。

核心数据结构

eventpoll

eventpoll 就是 epoll 的控制中心,红黑树管着监听 fd,rdllist 是触发事件队列,wq 是 epoll_wait 阻塞队列,poll_wait 给 file->poll 用,锁保护多核并发。事件触发靠回调,回调唤醒 epoll_wait,事件放到 rdllist。

/** This structure is stored inside the "private_data" member of the file* structure and represents the main data structure for the eventpoll* interface.*/
struct eventpoll {/** This mutex is used to ensure that files are not removed* while epoll is using them. This is held during the event* collection loop, the file cleanup path, the epoll file exit* code and the ctl operations.*/struct mutex mtx;/* Wait queue used by sys_epoll_wait() */wait_queue_head_t wq;/* Wait queue used by file->poll() */wait_queue_head_t poll_wait;/* List of ready file descriptors */struct list_head rdllist;/* Lock which protects rdllist and ovflist */rwlock_t lock;/* RB tree root used to store monitored fd structs */struct rb_root_cached rbr;/** This is a single linked list that chains all the "struct epitem" that* happened while transferring ready events to userspace w/out* holding ->lock.*/struct epitem *ovflist;/* wakeup_source used when ep_scan_ready_list is running */struct wakeup_source *ws;/* The user that created the eventpoll descriptor */struct user_struct *user;struct file *file;/* used to optimize loop detection check */int visited;struct list_head visited_list_link;#ifdef CONFIG_NET_RX_BUSY_POLL/* used to track busy poll napi_id */unsigned int napi_id;
#endif
};
成员描述
mtx全局互斥锁,保证在事件收集、关闭 fd、epoll_ctl 操作时对 epoll 的一致性。
wqepoll_wait 阻塞队列,当没有事件时,调用 epoll_wait 的进程挂在这里。
poll_waitfile->poll() 用的等待队列,内核中 poll 实现底层回调时用到。
rdllist就绪事件链表,当 fd 触发了事件,内核会把对应 epitem 放到这里,供 epoll_wait 返回给用户。
ovflist单链表,当 rdllist 被锁定遍历,向用户空间发送数据时,rdllist 不允许被修改,新触发的就绪 epitem 被 ovflist 串联起来,等待 rdllist 被处理完了,重新将 ovflist 数据写入 rdllist。 详看 ep_scan_ready_list 逻辑。
user拥有这个 epoll 的用户,做内核权限检查、资源限制等用途。
lock锁,保护 rdllist 和 ovflist 。
rbr红黑树根节点,用来管理所有注册到 epoll 的 fd(epitem)。
fileeventpoll 对应的文件结构,Linux 一切皆文件,用 vfs 管理数据。
napi_id应用于中断缓解技术。

epitem

epitem 是 epoll 里管理单个 fd 事件状态的核心单元,红黑树挂 rbn,就绪事件挂 rdllist,等待队列挂 pwqlist,拷贝用户关心事件在 event 里,容器指针 ep,fd 信息 ffd,控制能高效组织+高效唤醒。

/** Each file descriptor added to the eventpoll interface will* have an entry of this type linked to the "rbr" RB tree.* Avoid increasing the size of this struct, there can be many thousands* of these on a server and we do not want this to take another cache line.*/
struct epitem {union {/* RB tree node links this structure to the eventpoll RB tree */struct rb_node rbn;/* Used to free the struct epitem */struct rcu_head rcu;};/* List header used to link this structure to the eventpoll ready list */struct list_head rdllink;/** Works together "struct eventpoll"->ovflist in keeping the* single linked chain of items.*/struct epitem *next;/* The file descriptor information this item refers to */struct epoll_filefd ffd;/* Number of active wait queue attached to poll operations */int nwait;/* List containing poll wait queues */struct list_head pwqlist;/* The "container" of this item */struct eventpoll *ep;/* List header used to link this item to the "struct file" items list */struct list_head fllink;/* wakeup_source used when EPOLLWAKEUP is set */struct wakeup_source __rcu *ws;/* The structure that describe the interested events and the source fd */struct epoll_event event;
};
成员描述
rbn挂在 eventpoll->rbr 红黑树上。
rcu当需要释放 epitem 时用 RCU 延迟删除。
rdllink链接到 eventpoll->rdllist,表示就绪事件。当 fd 有事件触发,内核就把它放到 rdllist 里。
next用来维护 eventpoll->ovflist 单向链表的 next 指针,避免拷贝事件到用户空间时遗漏新的事件。
ffd记录节点对应的 fd 和 file 文件信息。
nwait等待队列个数。
pwqlist等待事件回调队列。当数据进入网卡,底层中断执行 ep_poll_callback。
epeventpoll 指针,epitem 关联 eventpoll。
fllinkepoll 文件链表结点,与 epoll 文件链表进行关联 file.f_ep_links。参考 fs.h, struct file 结构。
wsEPOLLWAKEUP 模式下使用。
event用户关注的事件。

epoll 的网络服务器流程图

image.png

初始化阶段

  • socket():创建 server_fd
  • bind():绑定 IP 和端口
  • fcntl():设置非阻塞模式(O_NONBLOCK)
  • listen():监听端口,准备接收连接

epoll 创建 & 注册

epoll_fd = epoll_create()
epoll_ctl(epoll_fd, EPOLL_CTL_ADD, server_fd, EPOLLIN)
  • epoll_create():创建 epoll 实例,得到 epoll_fd
  • epoll_ctl(EPOLL_CTL_ADD):将 server_fd 加入 epoll_fd,监听 EPOLLIN(监听是否有新连接)

事件循环

epoll_wait(epoll_fd, events, ...)
  • epoll_wait():阻塞等待事件,如果有事件触发(新连接 / 客户端读写事件),返回事件数组

处理新连接(server_fd 可读)

if (server_fd == events[i].data.fd) {client_fd = accept(server_fd);  // 非阻塞 acceptfcntl(client_fd, O_NONBLOCK);  // 设置非阻塞epoll_ctl(EPOLL_CTL_ADD, client_fd, EPOLLIN);  // 监控 client_fd
}
  • accept() 接收新连接,得到 client_fd
  • 设置 client_fd 非阻塞
  • epoll_ctl(EPOLL_CTL_ADD),监听 client_fdEPOLLIN

处理客户端数据(client_fd 可读)

if (client_fd 有 EPOLLIN 事件) {ret = read(client_fd, buf, size);  // 非阻塞 readif (ret > 0) {// 正常读取数据,处理业务逻辑} else if (ret == 0 || (ret == -1 && errno != EAGAIN)) {// 客户端关闭连接或出错close(client_fd);epoll_ctl(EPOLL_CTL_DEL, client_fd);  // 移除监控}// EAGAIN 表示数据未就绪,继续等待
}
  • 如果 EPOLLIN:说明 client_fd 有数据可读,调用 read()
    • ret > 0:正常读取数据,进行业务处理。
    • ret == 0:客户端关闭连接,关闭 client_fd 并从 epoll 移除。
    • ret == -1 && errno == EAGAIN:数据未就绪(非阻塞模式),继续等待。

处理客户端写入(EPOLLOUT 事件)

if (需要向 client_fd 写入数据) {epoll_ctl(EPOLL_CTL_MOD, client_fd, EPOLLOUT);  // 关注可写事件
}if (client_fd 有 EPOLLOUT 事件) {ret = write(client_fd, buf, size);  // 非阻塞 writeif (ret == -1 && errno == EAGAIN) {// 缓冲区满,稍后重试} else if (ret >= 0) {// 写入成功,恢复监控 EPOLLINepoll_ctl(EPOLL_CTL_MOD, client_fd, EPOLLIN);} else {// 写入失败,关闭连接close(client_fd);epoll_ctl(EPOLL_CTL_DEL, client_fd);}
}
  • 如果 EPOLLOUT:说明 client_fd 可写,调用 write()
    • ret >= 0:写入成功,恢复监控 EPOLLIN
    • ret == -1 && errno == EAGAIN:缓冲区满,稍后重试。

关闭连接

  • close() 关闭 server_fd 和所有 client_fd,结束服务

TCP + epoll 流程图

image.png

这是一张 Linux 5.0.1 内核下基于 epoll 的网络编程及 TCP 连接建立相关的流程图,涵盖了从客户端连接请求到服务器端处理的多个环节,下面我简单介绍一下流程:

epoll_create

  • 创建 eventpoll 结构体,初始化红黑树 rbr 和就绪队列 rdlist
  • 返回 epoll_fd

epoll_ctl

  • EPOLL_CTL_ADD 把目标 fd 包装成 epitem 节点
  • 挂到 eventpoll->rbr 红黑树里
  • 建立 sock->sk_wq 的回调 ep_poll_callback

③ 监听事件队列

  • epitem 挂到 socket->wq->wait_queue_head
  • 事件触发时由回调唤醒挂在 wait_queue 上的 epitem

epoll_wait

  • 把当前线程挂到 eventpoll->wq 上,进入 TASK_INTERRUPTIBLE
  • 调用 schedule() 让出 CPU 等待事件

⑤ 网络事件到达(TCP 三次握手)

  • 驱动收到网卡中断,触发 tcp_v4_rcv
  • 调用 sock_def_wakeup 唤醒 wait_queue 上的 epitem

ep_poll_callback

  • 将就绪的 epitem 节点挂到 eventpoll->rdlist
  • 设置 wake_up_flag 唤醒 epoll_wait

⑦ 唤醒 epoll_wait

  • wake_up_locked 唤醒 epoll 阻塞的线程

ep_send_events

  • eventpoll->rdlist 中取出就绪事件
  • 返回到用户空间的 events 数组

⑨ 用户态 accept 连接

  • 获取 client_fd,再次 epoll_ctl 加入监听

epoll 的应用场景

高并发网络服务器

例如:Web 服务器(如 Nginx、C++ WebServer 项目),Chat Server(即时通讯服务器),游戏服务器,HTTP Proxy。

为什么用 epoll:支持成千上万的并发连接,不像 select/poll 那样有 FD 数量上限(select 1024),事件通知机制效率高(epoll_wait 只返回活跃 FD)。


高并发客户端程序

例如:爬虫系统(需要同时维护大量 HTTP/TCP 连接),高并发消息队列消费者,WebSocket 客户端集群。

为什么用 epoll:维护大量 socket,避免频繁阻塞或线程爆炸,支持非阻塞 IO,高效回调处理响应。


长连接服务场景

例如:IM 服务,实时推送服务,股票/期货交易系统行情推送,实时视频/音频流服务。

为什么用 epoll:长连接数量庞大,短时间内事件数量较少,epoll事件回调机制极其适合,配合 ET 模式,减少 epoll_wait 调用次数,提高效率。


多 IO 设备场景

例如:高性能日志系统,文件同步/备份系统(同时监听大量文件 IO 事件),异步文件下载器/上传器。

为什么用 epoll:能同时监听多设备 IO 事件,不必阻塞等待单个 IO 完成。

参考资料:

epoll(4) - Linux man page(Linux man 手册)

[内核源码] epoll 实现原理

相关文章:

Linux epoll 详解:概念、使用、数据结构、流程及应用

epoll是什么&#xff1f; epoll 是从 Linux 2.6 起&#xff0c;Linux内核提供的一种高性能I/O事件通知机制&#xff0c;用于解决传统 select 和 poll 在处理大量并发连接时遍历、最大数量限制、频繁拷贝数据等问题。epoll 可以用来监听多个文件描述符&#xff08;socket、管道…...

Kubernetes排错(十一):lsof命令实战场景

在Kubernetes生产环境中&#xff0c;lsof作为Linux系统的"透视眼"&#xff0c;是排查容器级疑难杂症的必备工具。本文将深入解析其在容器化场景下的高阶用法&#xff0c;助你快速定位隐藏问题。 一、基础环境准备 1. 容器内安装lsof # 临时进入容器安装&#xff0…...

Java基础语法之循环结构

循环结构 1.定义 控制一段代码重复执行多次 2.分类 2.1 for循环 2.1.1 定义 控制一段代码反复执行很多次。 2.1.2 for循环格式 for (初始化语句; 循环条件; 迭代语句) { 循环体语句(重复执行的代码); }示例 // 输出3次HelloWorld for (int i 0; i < 3; i) { System…...

冒泡排序的原理

冒泡排序是一种简单的排序算法&#xff0c;它通过重复地遍历待排序的列表&#xff0c;比较相邻的元素并交换它们的位置来实现排序。具体原理如下&#xff1a; 冒泡排序的基本思想 冒泡排序的核心思想是通过相邻元素的比较和交换&#xff0c;将较大的元素逐步“冒泡”到列表的…...

AUTOSAR图解==>AUTOSAR_TR_InteractionWithBehavioralModels

AUTOSAR与行为模型交互详解 深入解析AUTOSAR软件组件与行为模型的交互关系与转换机制 目录 引言 1.1 AUTOSAR编辑工具概述 1.2 源起与目标 1.3 术语定义需求追溯AUTOSAR中行为建模的用例 3.1 软件组件的行为建模 3.2 软件组件描述到行为模型 3.3 行为模型到软件组件描述 3.4 组…...

GO语言内存管理结构

文章目录 1、内存分区1.1、栈&#xff08;Stack&#xff09;1.2、堆&#xff08;Heap&#xff09; 2、堆内存管理结构2.1、内存分配器&#xff08;MCache → MArena → MSpan → MHeap&#xff09;2.2、大小分类&#xff08;Size Class&#xff09;2.3、分配流程 3、垃圾回收&a…...

分享一些资料供大家学习

群里收集来的&#xff0c;自己感觉还是比较经典的&#xff0c;希望大家喜欢&#xff01;&#xff01;&#xff01; 20250428 夸克网盘分享一大波经典IT架构好货20250429夸克网盘分享精品文档-管理咨询师必备的思维模型20250430夸克网盘分享清华大学DeepSeek教程又来了《文科生A…...

RAGMCP基本原理说明和相关问题解惑

一、RAG架构原理和局限性 1.1 概念解释 RAG&#xff08;Retrieval-Augmented Generation&#xff09;&#xff1a;检索增强生成&#xff0c;让大模型接受外部输入后&#xff0c;总结输出 向量数据库&#xff1a;向量数据通常是高维空间中的点&#xff0c;代表复杂的数据结构…...

PyGame游戏开发(含源码+演示视频+开结题报告+设计文档)

前言&#xff1a; 大二小学期python课上基于pygame做的一个游戏小demo&#xff0c;当时老师花了一天讲解了下python基础语法后&#xff08;也是整个大学四年唯一学习python的时间&#xff09;&#xff0c;便让我们自学网课一周然后交项目&#xff0c;所以做的非常仓促&#xff…...

Git标签

Git标签 1. 添加标签 使用 tag 命令可以给某次 commit 提交的版本打上标签&#xff0c;相当于这个 commit id 的别名&#xff0c;在实践中&#xff0c;会使用 v1.0 之类的标签提示这是正式版的第一个版本。 git tag v1.0 [commit id]缺省输入 commit id会给最新的一次提交打…...

USB学习【6】USB传输错误的处理

1.前言 我们从物理层到信号层&#xff0c;到协议层&#xff0c;他们分别在不同的层面完成不同的功能。 总结一下&#xff1a; 物理层实现了高低电平的检测。 信号层更进一步&#xff0c;通过一些方法&#xff0c;实现了二进制的传输。 协议层&#xff0c;因为可以二进制传输了…...

深入解析 Vision Transformer (ViT) 与其在计算机视觉中的应用

在近年来&#xff0c;深度学习尤其在计算机视觉领域取得了巨大的进展&#xff0c;而 Vision Transformer&#xff08;ViT&#xff09;作为一种新的视觉模型&#xff0c;它的表现甚至在许多任务中超过了传统的卷积神经网络&#xff08;CNN&#xff09;&#xff0c;如 ResNet。在…...

《Go小技巧易错点100例》第三十一篇

本期分享&#xff1a; 1.Go struct内存对齐 2.使用空结构体(struct{})节省内存 Go struct内存对齐 在计算机系统中&#xff0c;CPU 访问内存时并不是逐字节读取的&#xff0c;而是以特定大小的块&#xff08;通常为 4/8 字节&#xff09;为单位进行读取。当数据的内存地址正…...

全栈项目实战:Vue3+Node.js开发博客系统

全栈项目实战&#xff1a;Vue3Node.js开发博客系统 一、项目架构设计 1. 技术栈选型 前端技术栈&#xff1a; Vue 3 Composition APITypeScriptPinia状态管理Vue Router 4Element Plus UI组件库Vite构建工具 后端技术栈&#xff1a; Node.js (Express/Koa)MongoDB (Mong…...

查看YOLO版本的三种方法

查看YOLO版本的三种方法&#xff1a; 一、通过命令行直接查询 使用Python交互式查询&#xff1a; from ultralytics import __version__ print(__version__) # 示例输出: 11.0.5二、检查PyTorch环境兼容性 import torch, ultralytics print(f"PyTorch: {torch.__versi…...

基于Docker的Bitwarden的私有本地部署

基于Docker的Bitwarden的私有本地部署 文章目录 基于Docker的Bitwarden的私有本地部署 本文首发地址 https://h89.cn/archives/355.html bitwarden 默认连接的是国外服务器 https://bitwarden.com/ &#xff0c;连接不是很稳定&#xff0c;也没有安全感&#xff0c;所以我选择了…...

点和体素哪个好

3D 深度学习中基于体素和基于点云的方法哪种更优&#xff1f;-腾讯云开发者社区-腾讯云 https://zhuanlan.zhihu.com/p/372497398 GitHub - open-mmlab/OpenPCDet: OpenPCDet Toolbox for LiDAR-based 3D Object Detection....

C++ STL编程 vector空间预留、vector高效删除、vector数据排序、vector代码练习

vector空间预留&#xff0c;作用是避免申请每次申请内存&#xff0c;提高运行效率。 对应的接口是 vector.reverse() vector的高效删除&#xff0c;对应的代码见下&#xff0c;一个时间复杂度是n&#xff0c;一个时间复杂度是1 #include<iostream> #include<vector…...

Android架构模式推荐及分析和MVC架构模式制作一个简单的底部tab切换

目录 主流架构模式对比 适用场景 MVP‌&#xff1a;团队协作开发,需要高可测试性的项目 MVC架构模式制作一个简单的底部tab切换 &#xff08;Model-View-Controller&#xff09;结构 代码 效果 主流架构模式对比 ‌对比维度‌‌MVC‌ ‌MVP‌ ‌MVVM‌ ‌MVI‌ ‌学习…...

【PVE】ProxmoxVE8虚拟机,存储管理(host磁盘扩容,qcow2/vmdk导入vm,vm磁盘导出与迁移等)

【PVE】ProxmoxVE8虚拟机&#xff0c;存储管理&#xff08;host磁盘扩容&#xff0c;qcow2/vmdk导入vm&#xff0c;vm磁盘导出与迁移等&#xff09; 文章目录 1、host 磁盘扩容2、qcow2/vmdk导入vm3、vm 磁盘导出与迁移 1、host 磁盘扩容 如何给host扩容磁盘&#xff0c;如增加…...

【JEECG 组件扩展】JSwitch开关组件扩展单个多选框样式

功能说明&#xff1a; 基于JeecgBoot开源框架&#xff0c;JSwitch开关组件扩展&#xff0c;支持单个多选样式。 效果展示&#xff1a; 使用示例&#xff1a; {field: JSwitch,component: JSwitch,label: JSwitch,},{field: JSwitchCheckBox,component: JSwitch,label: JSwitch…...

卷积神经网络-从零开始构建一个卷积神经网络

目录 一、什么是卷积神经网络CNN 1.1、核心概念 1.2、卷积层 二、什么是卷积计算 2.1、卷积计算的例子: 2.2、点积 2.3、卷积与点积的关系 2.4、Padding(填充) 2.4.1、Padding的主要作用 1、控制输出特征图尺寸 2、保留边缘信息 3. 支持深层网络训练 2.4.2、Str…...

Linux 常用命令集合

以下是一份 Linux 常用命令集合&#xff0c;涵盖文件操作、系统管理、网络管理、权限管理、进程管理等常见任务&#xff0c;并附上代码示例&#xff1a; 1. 文件与目录操作 命令作用示例ls列出目录内容ls -l&#xff08;详细列表&#xff09; ls -a&#xff08;显示隐藏文件&a…...

STM32f103 标准库 零基础学习之按键点灯(不涉及中断)

注意&#xff0c;此次代码不涉及中断&#xff0c;不涉及中断&#xff0c;不涉及中断 目录 1.初始化LED 2.初始化按键 3.粗略的延时函数 4.判断引脚电平 5.通过异或反转电平 开始 │ ├── 初始化LED&#xff08;GPIOA Pin1 推挽输出&#xff09; ├── 初始化按键&…...

【c++】【数据结构】二叉搜索树详解

目录 二叉搜索树的定义二叉搜索树的模拟实现查找函数循环版递归版 插入函数循环版递归版 删除函数循环版递归版 二叉搜索树的定义 二叉搜索树是一种特别的二叉树&#xff0c;是二叉树的搜索特化版。学过排序的都知道&#xff0c;在数组有序的情况下二分查找可以以极高的频率找…...

高精地图数据错误的侵权责任认定与应对之道

首席数据官高鹏律师团队 在自动驾驶与智慧交通快速发展的今天&#xff0c;高精地图作为核心基础设施&#xff0c;其数据准确性直接关系到公共安全。然而&#xff0c;技术并非完美&#xff0c;一旦因地图数据错误导致事故或损失&#xff0c;比如当自动驾驶汽车因高精地图数据错…...

Python训练营打卡——DAY22(2025.5.11)

复习日 学习参考如何使用kaggle平台&#xff0c;写下使用注意点&#xff0c;并对下述比赛提交代码 泰坦尼克号——来自灾难的机器学习 数据来源&#xff1a; kaggle泰坦里克号人员生还预测 挑战 泰坦尼克号沉没是历史上最臭名昭著的海难之一。 1912年4月15日&#xff0c;在被普…...

【计算机视觉】OpenCV实战项目 :Image_Cartooning_Web_App:基于深度学习的图像卡通化

Image_Cartooning_Web_App&#xff1a;基于深度学习的图像卡通化Web应用深度解析 1. 项目概述2. 技术原理与模型架构2.1 核心算法2.2 系统架构 3. 实战部署指南3.1 环境配置3.2 模型部署3.3 处理流程示例 4. 常见问题与解决方案4.1 模型加载失败4.2 显存溢出4.3 边缘伪影 5. 关…...

王道计算机网络知识点总结

计算机网络知识点总结 一、计算机网络体系结构 &#xff08;一&#xff09;计算机网络概述 计算机网络概念&#xff1a;互连的、自治的计算机系统的集合&#xff0c;目的是资源共享&#xff0c;组成包括多台自治计算机&#xff0c;规则是网络协议。 计算机网络的组成&#…...

Java学习笔记(对象)

一、对象本质 状态&#xff08;State&#xff09;&#xff1a;通过成员变量&#xff08;Field&#xff09;描述 行为&#xff08;Behavior&#xff09;&#xff1a;通过成员方法&#xff08;Method&#xff09;实现 class Person {String name;int age;void eat() {System.o…...

并发笔记-给数据上锁(二)

文章目录 核心挑战 (The CRUX)29.1 并发计数器 (Concurrent Counters)1. 简单非并发计数器 (Figure 29.1)2. 同步计数器&#xff08;单锁版本 - Coarse-Grained Lock, Figure 29.2&#xff09;3. 可伸缩计数&#xff1a;近似/懒惰计数器 (Approximate/Sloppy Counter, Figure 2…...

Three.js + React 实战系列 - 页脚区域 Footer 组件 ✨

对个人主页设计和实现感兴趣的朋友可以订阅我的专栏哦&#xff01;&#xff01;谢谢大家&#xff01;&#xff01;&#xff01; 为个人主页画上完美句号&#xff1a;设计一个美观实用的页脚组件 在完成 Hero、About、Projects、Contact 等模块后&#xff0c;我们为整个页面添上…...

基于Flask、Bootstrap及深度学习的水库智能监测分析平台

基于Flask、Bootstrap及深度学习的水库智能监测分析平台 项目介绍 本项目是基于Flask框架构建的水库智能监测分析平台&#xff0c;集水库数据管理、实时监测预警、可视化分析和智能预测功能于一体。 预测水位的预警级别&#xff1a;蓝色预警没有超过正常水位且接近正常水位1米…...

JavaSE核心知识点02面向对象编程02-08(异常处理)

&#x1f91f;致敬读者 &#x1f7e9;感谢阅读&#x1f7e6;笑口常开&#x1f7ea;生日快乐⬛早点睡觉 &#x1f4d8;博主相关 &#x1f7e7;博主信息&#x1f7e8;博客首页&#x1f7eb;专栏推荐&#x1f7e5;活动信息 文章目录 JavaSE核心知识点02面向对象编程02-08&#…...

7系列 之 SelectIO 资源

背景 《ug471_7Series_SelectIO.pdf》介绍了Xilinx 7 系列 SelectIO 的输入/输出特性及逻辑资源的相关内容。 第 1 章《SelectIO Resources》介绍了输出驱动器和输入接收器的电气特性&#xff0c;并通过大量实例解析了各类标准接口的实现。 第 2 章《SelectIO Logic Resource…...

【目标检测系列】YOLOV1解读

目标检测系列文章 目录 目标检测系列文章&#x1f4c4; 论文标题&#x1f9e0; 论文逻辑梳理1. 引言部分梳理 (动机与思想) &#x1f4dd; 三句话总结&#x1f50d; 方法逻辑梳理&#x1f680; 关键创新点&#x1f517; 方法流程图关键疑问解答Q1: 关于 YOLOv1 中的 "conf…...

GIF图像技术介绍

以下是对GIF格式的详细介绍,涵盖其定义、发展历程、技术特性、应用场景及与其他格式的对比: 一、GIF的定义与起源 GIF(Graphics Interchange Format,图形交换格式)由美国CompuServe公司于1987年推出,旨在解决早期互联网带宽不足的问题。其开发者Steve Wilhite采用LZW无损…...

【TI MSPM0】CCS工程管理

一、关于WORKSPACE 1.导入工程路径 导入工程时&#xff0c;实际是将工程从原路径复制到了Workspace路径下&#xff08;默认是在C盘user路径下&#xff09; 2.工程保存备份 关于工程的保存&#xff0c;可以右击文件夹&#xff0c;点击Reveal打开文件夹 将对应的文件夹进行复…...

牛客周赛 Round 92-题解

牛客周赛 Round 92-题解 A-小红的签到题 code #include<iostream> #include<string> using namespace std; string s; int main() {int n;cin >> n;cout << "a_";for (int i 0; i < n - 2; i )cout << b;return 0; }B-小红的模…...

iVX 图形化编程平台:结合 AI 原生开发的革新与实践

一、技术架构&#xff1a;重构 AI 与编程的交互逻辑 1. 信息密度革命&#xff1a;从线性代码到图形化语义单元 传统文本编程存在显著的信息密度瓶颈。以 "按钮点击→条件判断→调用接口→弹窗反馈" 流程为例&#xff0c;Python 实现需定义函数、处理缩进并编写 30 …...

微服务架构中如何保证服务间通讯的安全

在微服务架构中,保证服务间通信的安全至关重要。服务间的通信通常是通过HTTP、gRPC、消息队列等方式实现的,而这些通信链路可能面临多种安全风险。为了应对这些风险,可以采取多种措施来保证通信安全。 常见的服务间通信风险 1.数据泄露:在服务间通信过程中,敏感数据可能会…...

长短期记忆网络(LSTM)深度解析:从理论到实践的全方位指南

一、LSTM基础理论:超越传统RNN的记忆架构 1.1 RNN的长期依赖问题 传统循环神经网络(RNN)在处理长序列时面临的根本挑战是梯度消失/爆炸问题。当序列长度超过10-20个时间步时,RNN难以学习到早期时间步的信息。数学上,这源于反向传播过程中梯度的链式法则: 复制 下载 ∂…...

FramePack AI图片生成视频 v1.1 整合包

今天&#xff0c;我兴奋地要为大家介绍一款革命性的AI工具——FramePack&#xff0c;这是一个让人眼前一亮的图生视频整合包。想象一下&#xff0c;在2025年5月11日的今天&#xff0c;哪怕你的电脑显存仅有6G&#xff0c;你也可以轻松创造艺术&#xff01; FramePack的神奇之处…...

在 C++中,指针数组与数组指针的区别

1. 指针数组:本质上是一个数组,数组中的每个元素都是一个指针。也就是说,这个数组存储的是多个指针变量,这些指针可以指向不同的对象(比如不同的变量、数组等) 。 2. 数组指针:本质上是一个指针,这个指针指向一个数组。即它指向的是数组的首地址,通过这个指针可以操作…...

Ubuntu 24服务器部署abp vnext应用程序的完整教程

一、服务器配置 1、安装Nginx 2、安装.NetCore SDK 或.NetCore 运行时 以上两步参考 《UbuntuNginxSupervisord部署.net core web应用程序_nginx部署netcore-CSDN博客》 二、abp vnext程序部署 1、程序发布 使用VS进行发布 2、程序上传 使用winSCP工具 3、openiddict…...

Ingrees 控制器与 Ingress 资源的区别

在 Kubernetes 中&#xff0c;单纯的 Ingress 资源定义文件&#xff08;YAML&#xff09;本身不会直接创建 Pod。Ingress 的作用是定义路由规则&#xff08;如将外部流量路由到集群内的服务&#xff09;&#xff0c;而实际处理流量的 Pod 是由 Ingress 控制器&#xff08;如 Ng…...

动态路由实现原理及前端控制与后端控制的核心差异

在 Web 开发领域&#xff0c;动态路由是构建灵活、高效应用的关键技术之一。它能够根据不同的条件和请求&#xff0c;动态地决定页面的跳转和数据的加载&#xff0c;极大提升用户体验。本文将深入剖析动态路由的实现原理&#xff0c;并详细探讨前端控制和后端控制两种模式的最大…...

stm32 WDG看门狗

目录 stm32 WDG看门狗一、WDG基础知识1&#xff09;WDG&#xff08;Watchdog&#xff09;看门狗简介 二、IWDG独立看门狗1&#xff09;IWDG键寄存器2&#xff09;IWDG超时时间 三、WWDG窗口看门狗1&#xff09;WWDG框图2&#xff09;WWDG工作特性3&#xff09;WWDG超时时间4&am…...

MySQL索引详解(下)(SQL性能分析,索引使用)

索引是MySQL性能优化的核心&#xff0c;但如何精准分析查询瓶颈、合理设计索引&#xff0c;是开发者必须掌握的技能。本文结合实战案例&#xff0c;系统讲解SQL性能分析工具链与索引使用技巧&#xff0c;帮助读者构建高性能数据库系统。 一、SQL性能分析&#xff1a;从宏观到微…...

添加文字标签

上节我们学会了如何在地图中标记位置,那么可不可以为地图添加文字注释呢?答案是肯定的,我们依旧以广州塔为例. //添加文字标签和广告牌var label viewer.entities.add({position: Cesium.Cartesian3.fromDegrees(113.3191,23.109,100),label:{text:"广州塔",font:&…...