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

多路转接epoll原理详解

目录

从epoll接口入手

创建epoll模型

用户告诉内核关心的事件

内核告诉用户就绪的事件

epoll的原理

整体思路

如何判断事件是否就绪

事件就绪后如何实现将节点插入就绪队列


从epoll接口入手

本篇文章从epoll的三个接口入手介绍epoll的具体工作原理

创建epoll模型

#include <sys/epoll.h>
int epoll_create(int size);

创建一个epoll的句柄,从linux-2.6.8后,size参数是被忽略的,用完之后必须调用close关闭。

返回值实际上就是一个文件描述符

用户告诉内核关心的事件

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

 epoll作为多路转接的方案,依然要解决如何让操作系统知道用户关心哪些文件描述符的哪些事件的问题,这个接口解决的就是这个问题。epfd是epoll_create返回的文件描述符,op表示动作,用三个宏来表示。

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

fd是用户关心的文件描述符,最后一个参数event告诉内核要监听fd上的哪些事件,再来看看epoll_event的结构

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

events是事件类型,有以下几个宏

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

关于epoll_data这个结构,在写代码时还会细谈

内核告诉用户就绪的事件

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

epfd依然是epoll_create的返回值,events和maxevents确定了一个epoll_event的数组,这个数组包含了哪些文件描述符的哪些事件就绪的信息,timeout是超时时间,返回值与select和poll一样

为0表示超时返回;为-1表示有错误发生,并设置错误码errno;为正数表示在timeout时间内事件就绪的文件描述符个数

epoll的原理

整体思路

有了使用epoll的宏观认识后,再来详细谈谈工作原理

先来看看上面第一个接口所说的创建epoll模型,这个epoll模型到底是什么

以下代码来自linux-2.6.18的源码(使用vscode打开源码根目录可以搜索到下面的代码)

/** This structure is stored inside the "private_data" member of the file* structure and rapresent the main data sructure for the eventpoll* interface.*/
struct eventpoll {/* Protect the this structure access */rwlock_t lock;/** This semaphore is used to ensure that files are not removed* while epoll is using them. This is read-held during the event* collection loop and it is write-held during the file cleanup* path, the epoll file exit code and the ctl operations.*/struct rw_semaphore sem;/* 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;/* RB-Tree root used to store monitored fd structs */struct rb_root rbr;
};

eventpoll结构体就是epoll模型,重点来看rdllist和rbr两个字段,rbr是一颗红黑树,节点存放了文件描述符和事件的映射关系,里面存放的都是用户传入的的文件描述符,而如果某个文件描述符上的事件就绪了,就会将这个节点插入到rdllist中

rdllist是就绪队列,里面的节点都是已经就绪的文件描述符和对应的事件

所以用户使用epoll_ctl实际就是对这颗红黑树进行增删查改,而一旦有文件描述符就绪了,就会被加入rdllist中,epoll_wait实际上就会得到rdllist中存放的就绪文件描述符的信息。

下面是节点的结构体,可以看到有所属的红黑树的节点的信息,所属的等待队列的节点的信息

实际上,前文所说插入到rdllist并不是复制一个节点插入到rdllist里,而是修改这个节点的rdllink字段,让这个节点属于红黑树的同时,还属于等待队列

struct epitem {/* RB-Tree node used to link this structure to the eventpoll rb-tree */struct rb_node rbn;/* List header used to link this structure to the eventpoll ready list */struct list_head rdllink;/* 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;/* The structure that describe the interested events and the source fd */struct epoll_event event;/** Used to keep track of the usage count of the structure. This avoids* that the structure will desappear from underneath our processing.*/atomic_t usecnt;/* List header used to link this item to the "struct file" items list */struct list_head fllink;/* List header used to link the item to the transfer list */struct list_head txlink;/** This is used during the collection/transfer of events to userspace* to pin items empty events set.*/unsigned int revents;
};

如何判断事件是否就绪

接下来再谈谈epoll如何知道某个文件描述符的事件是否就绪

要解决这个问题,先从下面这个结构体开始

struct file {.../* needed for tty driver, and maybe others */void			*private_data;#ifdef CONFIG_EPOLL/* Used by fs/eventpoll.c to link all the hooks to this file */struct list_head	f_ep_links;spinlock_t		f_ep_lock;
#endif /* #ifdef CONFIG_EPOLL */struct address_space	*f_mapping;
};

重点关注这个private_data

当我们创建tcp或者udp套接字时,返回的实际上是文件描述符,内核通过这个文件描述符找到了对应的struct file结构,而这个结构的private_data字段就会指向套接字

struct socket {socket_state		state;unsigned long		flags;const struct proto_ops	*ops;struct fasync_struct	*fasync_list;struct file		*file;struct sock		*sk;wait_queue_head_t	wait;short			type;
};

可以看到socket中还有一个字段是file,这个file就是socket所属的那个struct file的地址

socket下还有sock结构体

struct sock {/** Now struct inet_timewait_sock also uses sock_common, so please just* don't add nothing before this first member (__sk_common) --acme*/...struct sk_buff_head	sk_receive_queue;struct sk_buff_head	sk_write_queue;struct sk_buff_head	sk_async_wait_queue;...
};

太长了省略了一些字段,sock中实际上是各种网络信息,这里最重要的两个就是接收队列和写队列,实际上就是接收缓冲区和发送缓冲区,至此,只需要判断接收缓冲区是否为空就能判断读事件是否就绪

之前说struct file的private_data字段指向struct socket其实还不够准确

我们在创建套接字时常常会指定创建tcp套接字或者udp套接字,private_data会指向这样的struct tcp_socket或者struct udp_socket,而这两个struct结构体实际上会间接包含strcut sock结构

struct tcp_sock {/* inet_connection_sock has to be the first member of tcp_sock */struct inet_connection_sock	inet_conn;...
};
struct inet_connection_sock {/* inet_sock has to be the first member! */struct inet_sock	  icsk_inet;...
};
struct inet_sock {/* sk and pinet6 has to be the first two members of inet_sock */struct sock		sk;...
};
struct udp_sock {/* inet_sock has to be the first member */struct inet_sock inet;...
};
struct inet_sock {/* sk and pinet6 has to be the first two members of inet_sock */struct sock		sk;...
};

可以看到tcp比udp多套了一个管理连接的结构体 struct inet_connection_sock,这里所展现的tcp_sock和udp_sock是一种继承体系,其中strcut sock可看成是基类,剩下的都是子类

而前面的struct socket结构体中的struct sock字段也可能并不是指向一个struct sock的对象,而是指向一个tcp_sock或者udp_sock对象,在需要用到对应tcp或者udp的方法时进行类型强转

这实际上也有一种多态的思想

事件就绪后如何实现将节点插入就绪队列

内核底层提供了一种回调机制,用于处理事件就绪时进行什么动作,默认这个回调是为空的,在epoll这里,这个回调被设置为当事件就绪后把节点插入就绪队列,于是,可以自动的在事件就绪时将节点插入就绪队列。

epoll的优点

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


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

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

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

相关文章:

多路转接epoll原理详解

目录 从epoll接口入手 创建epoll模型 用户告诉内核关心的事件 内核告诉用户就绪的事件 epoll的原理 整体思路 如何判断事件是否就绪 事件就绪后如何实现将节点插入就绪队列 从epoll接口入手 本篇文章从epoll的三个接口入手介绍epoll的具体工作原理 创建epoll模型 #in…...

基于 MCP用 Python 搭建 “大模型网关”在 MCP 服务器端聚合多个大模型的 API,将其统一为 MCP 协议接口

下面给出基于 MCP(Model-Connection-Protocol)设计思想,用 Python 搭建 “大模型网关” 的典型开发流程。整体思路是:在 MCP 服务器端聚合多个大模型的 API,将其统一为 MCP 协议接口;在客户端按需调用这些统一后的接口。总结如下: 概要: 需求与架构定位:Clarify 要接入…...

Linux的时间函数

ucos中有systick这个系统时间滴答&#xff0c;那linux中有没有这种系统时间滴答呢&#xff1f;有&#xff0c;jiffies&#xff0c;但是用户空间不可以使用。那么在linux中除了使用timer定时器进行定时&#xff0c;可以通过时间滴答的方式来进行粗略的计时吗&#xff1f;下面介绍…...

JCE cannot authenticate the provider BC

本地使用了加密类、并且运行正常、 用hutool做RSA加密时候出现这个问题的! import cn.hutool.core.codec.Base64; import cn.hutool.core.util.ArrayUtil; import cn.hutool.core.util.StrUtil; import cn.hutool.crypto.SecureUtil; import cn.hutool.crypto.SmUtil; import…...

4.1 融合架构设计:LLM与Agent的协同工作模型

大型语言模型&#xff08;Large Language Models, LLMs&#xff09;与智能代理&#xff08;Agent&#xff09;的融合架构已成为人工智能领域推动企业智能化的核心技术。这种协同工作模型利用LLM的语言理解、推理和生成能力&#xff0c;为Agent提供强大的知识支持&#xff0c;而…...

【Spec2MP:项目管理之项目风险管理】

在半导体行业竞争白热化的今天&#xff0c;一颗芯片从设计到量产的旅程犹如跨越重重险峰。据行业数据显示&#xff0c;30%的芯片项目因未及时识别风险导致延期交付&#xff0c;而55%的成本超支源于前期风险评估不足。这背后折射出一个核心命题&#xff1a;如何在复杂的技术攻关…...

【Axure教程】表格嵌套卡片

今天教大家制作表格嵌套卡片的原型模版&#xff0c;可以点击加号或减号展开或收起对应部门下的员工卡片信息。这个表格是用中继器制作的&#xff0c;所以使用也很方便&#xff0c;在中继器表格里维护数据&#xff0c;即可自动生成交互效果&#xff0c;具体效果可以打开下方原型…...

无人机动力核心测评:CKESC STONE 180A-M 电调

一、核心技术优势&#xff1a;全场景适配的智能控制方案 作为南昌长空科技的工业级产品&#xff0c;南昌长空的STONE 180A-M 电调以高可靠启动算法为核心&#xff0c;支持 6-14S 锂电输入&#xff0c;具备逆风启动稳定性与剧变油门抗丢相能力&#xff0c;实测油门响应时间 300…...

【回眸】Aurix TC397 IST 以太网 UDP 相关开发

前言 关于移植IST功能至 Infineon TC397上主要涉及到UDP发送报文及接收。IST是安全诊断相关的工作 Nvidia IST介绍 Orin系列芯片会提供一种机制来检测由系统内测&#xff08;IST&#xff09;所产生的永久的故障&#xff0c;IST 应该在 Orin-x 功能安全系统中使用期间被启动。…...

C语言别踩白块附源码

复制即可使用 #define _CRT_SECURE_NO_WARNINGS//一定要放在第一行 #include<stdio.h>//引用输入输出头文件&#xff0c;每一次都需要引用这个文件 #include<math.h> #include<string.h> #include<ctype.h> #include<stdlib.h> #include<io…...

centos7里memcached 的安装使用

memcahced 的概述 Memcached是一个自由开源的&#xff0c;高性能&#xff0c;分布式内存对象缓存系统。 Memcached是以LiveJournal旗下Danga Interactive公司的Brad Fitzpatric为首开发的一款软件。现在已成为mixi、hatena、Facebook、Vox、LiveJournal等众多服务中提高Web应…...

深入理解指针(3)

1.指针的使⽤和传址调⽤ 1.strlen的模拟实现 库函数strlen的功能是求字符串⻓度&#xff0c;统计的是字符串中\0 之前的字符的个数。函数原型如下&#xff1a; 参数str接收⼀个字符串的起始地址&#xff0c;然后开始统计字符串中 \0 之前的字符个数&#xff0c;最终返回⻓度。…...

第十届电气、电子和计算机工程研究国际学术研讨会(ISAEECE 2025)

重要信息 官网&#xff1a;www.isaeece.com&#xff08;点击了解参会投稿等&#xff09; 时间&#xff1a;2025年6月20-22日 地点&#xff1a;中国 ▪ 西安 征稿主题 电气、电子和计算机工程&#xff08;Electrical, Electronics and Computer Engineering, EECE&#xff09…...

RabbitMQ 中的队列声明

目录 一、为什么要声明队列&#xff1f;二、声明队列的基本语法参数说明 三、声明队列的示例代码示例 1&#xff1a;声明一个普通的队列示例 2&#xff1a;声明一个持久化队列示例 3&#xff1a;声明一个带 TTL 的队列 四、注意事项五、总结 在 RabbitMQ 中&#xff0c;队列是消…...

unity Animation学习,精准控制模型动画播放

unity 控制模型动画播放&#xff0c;Animation学习。 此脚本挂载在带有动画的模型上。 using System.Collections; using System.Collections.Generic; using UnityEngine;public class AnimationCtrl : MonoBehaviour {void Start(){PlayAnimation();//开始的时候调用播放动…...

大模型面经 | 春招、秋招算法面试常考八股文附答案(六)

大家好,我是皮先生!! 今天给大家分享一些关于大模型面试常见的面试题,希望对大家的面试有所帮助。 往期回顾: 大模型面经 | 春招、秋招算法面试常考八股文附答案(RAG专题一) 大模型面经 | 春招、秋招算法面试常考八股文附答案(RAG专题二) 大模型面经 | 春招、秋招算法…...

【深度学习】#9 现代循环神经网络

主要参考学习资料&#xff1a; 《动手学深度学习》阿斯顿张 等 著 【动手学深度学习 PyTorch版】哔哩哔哩跟李牧学AI 概述 门控循环单元和长短期记忆网络利用门控机制实现对序列输入的选择性记忆。深度循环神经网络堆叠多个循环神经网络层以实现更强的表达能力和特征提取能力。…...

《CBOW 词向量转化实战:让自然语言处理 “读懂” 文字背后的含义》

文章目录 前言一、自然语言模型统计语言模型存在的问题总结&#xff1a;这两个问题的本质&#xff0c;第一个是"容量问题"&#xff1a;模型记忆力有限&#xff1b;第二个是"理解力问题"&#xff1a;模型缺乏抽象能力。 二、词向量转换1.onehot编码编码过程…...

网络变更:APIC 节点替换

Draft 一、同版本硬件更换 1. 查看 APIC 状态 System > Controllers > (any APIC) > Cluster APIC1> acidiag avread // APIC 参数 2. 下线故障设备 Actions > Decommission 3. 物理移除故障设备,连接目标 APIC 4. 根据第一步中的配置参数配置目…...

Java在excel中导出动态曲线图DEMO

1、环境 JDK8 POI 5.2.3 Springboot2.7 2、DEMO pom <dependency><groupId>org.apache.poi</groupId><artifactId>poi-ooxml</artifactId><version>5.2.3</version></dependency><dependency><groupId>commons…...

Python爬虫爬取图片并存储到MongoDB(注意:仅尝试存储一条空的示例数据到MongoDB,验证MongoDB的联通性)

以下是一个使用Python爬取图片并存储到MongoDB的示例实现&#xff0c;包含详细步骤说明&#xff1a; import requests from bs4 import BeautifulSoup from pymongo import MongoClient from datetime import datetime import os import re# 配置信息 mongoIP mongodb://root…...

Qt —— 在Linux下试用QWebEngingView出现的Js错误问题解决(附上四种解决办法)

错误提示:js: A parser-blocking, cross site (i.e. different eTLD+1) script, https:xxxx, is invoked via document.write. The network request for this script MAY be blocked by the browser in this or a future page load due to poor network connectivity. If bloc…...

240424 leetcode exercises II

240424 leetcode exercises II jarringslee 文章目录 240424 leetcode exercises II[148. 排序链表](https://leetcode.cn/problems/sort-list/)&#x1f501;分治 & 归并排序法1. 找中点并断开2. 合并两个有序链表3. 主函数&#xff1a;递归拆分与合并 [24. 两两交换链表…...

STM32实现2小时延时的最佳方法探讨

在嵌入式系统开发中&#xff0c;特别是使用STM32这类微控制器时&#xff0c;实现精确的长时间延时是一项常见但具有挑战性的任务。延时的方法选择不仅影响系统的性能和功耗&#xff0c;还关系到系统的稳定性和可靠性。本文将探讨在STM32上实现2小时延时的几种方法&#xff0c;并…...

G3学习笔记

&#x1f368; 本文为&#x1f517;365天深度学习训练营 中的学习记录博客&#x1f356; 原作者&#xff1a;K同学啊 准备工作 import torch import numpy as np import torch.nn as nn import torch.optim as optim from torchvision import datasets, transforms from torc…...

初识Redis · 主从复制(上)

目录 前言&#xff1a; 主从模式 模拟主从模式 连接信息 slaveof命令 nagle算法 Nagle算法的工作原理&#xff1a; 具体实现&#xff1a; 优点&#xff1a; 缺点&#xff1a; 使用场景&#xff1a; 拓扑结构 前言&#xff1a; 主从复制这里算得上是一个大头了&…...

欧拉计划 Project Euler55(利克瑞尔数)题解

欧拉计划 Project Euler 55 题解 题干思路code 题干 思路 直接暴力找即可&#xff0c;若使用其他语言要注意溢出的问题&#xff0c;这里我使用的手写大数加法 code // 249 #include <bits/stdc.h>using namespace std;using ll long long;string add(const string&am…...

关于nginx,负载均衡是什么?它能给我们的业务带来什么?怎么去配置它?

User 关于nginx&#xff0c;我还想知道&#xff0c;负载均衡是什么&#xff1f;它能为我的业务带来什么&#xff1f;怎么去配置它&#xff1f; Assistant 负载均衡是 Nginx 另一个非常强大的功能&#xff0c;也是构建高可用、高性能应用的关键技术之一。我们来详细了解一下。 …...

【项目管理】进度网络图 笔记

项目管理-相关文档&#xff0c;希望互相学习&#xff0c;共同进步 风123456789&#xff5e;-CSDN博客 &#xff08;一&#xff09;知识总览 项目管理知识域 知识点&#xff1a; &#xff08;项目管理概论、立项管理、十大知识域、配置与变更管理、绩效域&#xff09; 对应&…...

【C++QT】Buttons 按钮控件详解

文章目录 一、QPushButton 基础按钮控件二、QToolButton 轻量工具按钮控件三、QRadioButton 互斥选择控件四、QCheckBox 状态选择控件五、QCommandLinkButton 引导式按钮控件六、QDialogButtonBox 对话框按钮布局控件七、实践与选型建议八、总结如果这篇文章对你有所帮助&#…...

威雅利电子|业界领先的高隔离度用于5G基站的吸收式SPDT开关“NT1819“

业界领先的高隔离度 用于5G基站的吸收式SPDT开关"NT1819" 为了实现智能社会&#xff0c;已经启动了5G服务。这样&#xff0c;高速、低延迟、大容量的数据通信成为可能&#xff0c;也给我们的生活和工业发展带来了巨大的变化。 在5G基站有很多天线&#xff0c;每个天…...

【DNS】BIND 9的配置

该文档围绕BIND 9的配置与区域文件展开&#xff0c;介绍了BIND 9配置文件及区域文件的相关知识&#xff0c;以及权威名称服务器、解析器的相关内容&#xff0c;还阐述了负载均衡和区域文件的详细知识&#xff0c;具体如下&#xff1a; 基础配置文件&#xff1a; named.conf&am…...

高可靠性厚铜板制造的关键设备与工艺投入

随着科技的不断发展&#xff0c;电子设备越来越普及&#xff0c;对电路板的需求也越来越大。厚铜板电路板作为一种高性能、高可靠性的电路板&#xff0c;受到了广泛的关注和应用。那么&#xff0c;作为一家厚铜板电路板供应商&#xff0c;如何投入线路板生产呢&#xff1f;本文…...

m365是什么,和o365的区别

M365&#xff08;Microsoft 365&#xff09;是微软推出的基于云的办公套件&#xff0c;包含多种生产力工具&#xff0c;旨在帮助个人和企业提高工作效率。它包括经典的办公软件&#xff0c;如Word、Excel、PowerPoint、Outlook等&#xff0c;还提供协作和云存储服务&#xff0c…...

【Pandas】pandas DataFrame dot

Pandas2.2 DataFrame Binary operator functions 方法描述DataFrame.add(other)用于执行 DataFrame 与另一个对象&#xff08;如 DataFrame、Series 或标量&#xff09;的逐元素加法操作DataFrame.add(other[, axis, level, fill_value])用于执行 DataFrame 与另一个对象&…...

技术服务业-首套运营商网络路由5G SA测试专网在深光搭建完成并对外提供服务

深光为了更好的服务蜂窝无线技术及运营商测试认证相关业务&#xff0c;搭建了技术服务业少有的5G测试专网&#xff0c;可独立灵活配置、完整端到端5G&#xff08;含RedCap、LAN&#xff09;的网络架构。 通过走真正运营商网络路由的方式&#xff0c;使终端设备的测试和运营商网…...

GrassRouter 小草MULE多5G多链路聚合通信路由设备在应急场景的聚合效率测试报告及解决方案

在应急通信场景中&#xff0c;快速、稳定、高效的通信链路是保障救援工作顺利开展的关键。MULE&#xff08;Multi-Link Unified Link Enhancement&#xff09;多链路聚合路由通信设备作为一种新型的通信技术解决方案&#xff0c;通过聚合多条通信链路&#xff08;如4G/5G、卫星…...

解释器模式:自定义语言解析与执行的设计模式

解释器模式&#xff1a;自定义语言解析与执行的设计模式 一、模式核心&#xff1a;定义语言文法并实现解释器处理句子 在软件开发中&#xff0c;当需要处理特定领域的语言&#xff08;如数学表达式、正则表达式、自定义配置语言&#xff09;时&#xff0c;可以通过解释器模式…...

第十二章 Python语言-大数据分析PySpark(终)

目录 一. PySpark前言介绍 二.基础准备 三.数据输入 四.数据计算 1.数据计算-map方法 2.数据计算-flatMap算子 3.数据计算-reduceByKey方法 4.数据计算-filter方法 5.数据计算-distinct方法 6.数据计算-sortBy方法 五.数据输出 1.输出Python对象 &#xff08;1&am…...

Oracle数据库巡检脚本

1.查询实例信息 SELECT INST_ID, INSTANCE_NAME, TO_CHAR(STARTUP_TIME, YYYY-MM-DD HH24:MI:SS) AS STARTUP_TIME FROM GV$INSTANCE ORDER BY INST_ID; 2.查看是否归档 archive log list 3.查看数据库参数 SELECT NAME , TYPE , VALUE FROM V$PARAMETER ORDER BY NAME; 4.…...

示例:Spring JDBC编程式事务

以下是一个完整的 Spring JDBC 编程式事务示例&#xff0c;包含批量插入、事务管理、XML 配置和单元测试&#xff1a; 1. 项目依赖&#xff08;pom.xml&#xff09; <dependencies><!-- Spring JDBC --><dependency><groupId>org.springframework<…...

Happens-Before 原则

Happens-Before 规则 Happens-Before是JMM的核心概念之一&#xff0c;是一种可见性模型&#xff0c;保障多线程环境下前一个操作的结果相对于后续操作是可见的。 程序顺序性&#xff0c;同一线程中前面代码的操作happens-before后续的任意操作。volatile变量规则&#xff0c;…...

怎样通过互联网访问内网 SVN (版本管理工具)提交代码更新?

你有没有遇到过这种情况&#xff1a;在公司或者家里搭了个 SVN 服务器&#xff08;用来存代码的&#xff09;&#xff0c;但出门在外想提交代码时&#xff0c;发现连不上&#xff1f; 这是因为 SVN 通常跑在内网&#xff0c;外网直接访问不了。 这时候就需要 “内网穿透” ——…...

Verilog 语法 (一)

Verilog 是硬件描述语言&#xff0c;在编译下载到 FPGA 之后&#xff0c; FPGA 会生成电路&#xff0c;所以 Verilog 全部是并行处理与运行的&#xff1b;C 语言是软件语言&#xff0c;编译下载到单片机 /CPU 之后&#xff0c;还是软件指令&#xff0c;而不会根据你的代…...

针对 Spring Boot 应用中常见的查询场景 (例如:分页查询、关联查询、聚合查询) 如何进行 SQL 优化?

通用优化原则&#xff08;适用于所有场景&#xff09;&#xff1a; 索引是基础: 确保 WHERE、JOIN、ORDER BY、GROUP BY 涉及的关键列都有合适的索引&#xff08;单列或联合索引&#xff09;。避免 SELECT *: 只查询业务需要的列&#xff0c;减少数据传输量和内存消耗。覆盖索…...

shadcn/radix-ui的tooltip高度定制arrow位置

尝试了半天&#xff0c;后来发现&#xff0c;不支持。。。。。就是不支持 那箭头只能居中 改side和align都没用&#xff0c;下面有在线实例 https://codesandbox.io/p/sandbox/radix-ui-slider-forked-zgn7hj?file%2Fsrc%2FApp.tsx%3A69%2C21 但是呢&#xff0c; 第一如果…...

ROS-真机向虚拟机器人映射

问题描述 ROS里的虚拟机械臂可以实现和真实机械臂的位置同步&#xff0c;真实机械臂如何动&#xff0c;ROS里的虚拟机械臂就如何动 效果 步骤 确保库卡机械臂端安装有EthernetKRL辅助软件和KUKAVARPROXY 6.1.101&#xff08;它是一个 TCP/IP 服务器 &#xff0c;可通过网络实…...

ap无法上线问题定位(交换机发包没有剥掉pvid tag)

一中学&#xff0c;新开的40台appoe交换机核心交换机旁挂ac出口路由的组网&#xff0c;反馈ap无法上线&#xff0c;让协助解决。 组网如下&#xff1a; 排查过程&#xff1a; 检查ac的配置&#xff0c;没有发现问题 发现配置没有问题&#xff0c;vlan1000配置子接口&#xff…...

Linux基础

03.Linux基础 了解VMware备份的两种方式 了解Linux系统文件系统 掌握Linux基础命令 备份操作系统 为什么要备份系统&#xff1f; 数据安全&#xff1a;防止因硬件故障、软件错误等原因导致的数据丢失。 系统恢复&#xff1a;快速恢复系统至正常状态&#xff0c;减少停机时…...

python函数与模块

目录 一&#xff1a;函数 1.无参函数 2.带参数函数 2.函数中变量中的作用域 4.内建函数 二&#xff1a;模块与包 1.模块 &#xff08;1&#xff09;模块定义 &#xff08;2&#xff09;模块导入 2.包 &#xff08;1&#xff09;包的使用 &#xff08;2&#xff09;_…...