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

I/O复用函数的使用——select

I/O复用函数的使用——select

目录

一、概念

二、select接口

2.1 基础概念

 2.2  使用 select 函数的标准输入读取代码

 2.3 基于 `select` 模型的多客户端 TCP 服务器实现


一、概念

i/o复用使得程序能同时监听多个文件描述符,可以提高程序性能。

之前为了让服务器能够服务多个客户端,我们使用多线程或多进程进行服务器的并发,意味着有多少个客户端就要产生很多进程。会浪费,开销很大。所以我们引入i/o复用

i/o复用方法select,poll,epoll可以帮助应用程序找到就绪描述符eg:老师检查作业,谁写完了谁举手,老师过去检查,不用一个一个等待去检查

二、select接口

2.1 基础概念

检测键盘是否有数据输入,如果有打印输出,没有就阻塞。select系统调用的用途是在一段指定时间内,监听用户感兴趣的文件描述符的可读,可写异常事件。

系统调用原型

#include <sys/select.h>int select(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *timeout);
  • nfds:需要监视的文件描述符的最大值加1(fd + 1),因为文件描述符是从0开始的

  • readfdswritefdsexceptfds:分别表示可读、可写和异常条件的文件描述符集合,程序调用select函数时,通过这三个参数传入自己感兴趣的文件描述符。

  • timeout:超时时间,可以是NULL(阻塞等待),或者指定超时时间(非阻塞等待)。

  • 成功时,返回就绪文件描述符的总数,超时没有任何描述符就绪则返回0,失败返回-1,如果在等待期间,程序收到信号则立即返回-1并设置error为EINTR  

  • fd_set:结构体,fd_mask,数组类型,fd_bits,数组名。用于存储和管理一组文件描述符  fd_set可以容纳1024个位  数组收集  描述符,把数组中的描述符添加到集合fd_set

  • fd_set结构体仅包含一个整型数组,该数组的每个元素的每一位bit标记一个文件描述符。fd_set能容纳的文件描述符数量由FD_SETSIZE指定,这就限制了select能同时处理的文件描述符的总量  

  • 由于位操作过于频繁,可以用一系列宏来访问fd_set结构体中的位

 

使用I/O复用技术(如selectpollepoll)来处理多个文件描述符(FD)的流程图

假设只有3和7上有数据,结构体集合经过select返回值为2,之后会测试和集合作比较看看对于的位是不是1,找到看哪个上面有数据

 2.2  使用 select 函数的标准输入读取代码

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <sys/select.h>
#include <time.h>#define STDIN  0 // 定义STDIN常量,表示标准输入的文件描述符int main()
{int fd = STDIN; // 将文件描述符fd初始化为标准输入fd_set fdset;   // 定义一个文件描述符集合fdsetwhile (1) // 无限循环,持续等待输入{FD_ZERO(&fdset); // 清空文件描述符集合fdsetFD_SET(fd, &fdset); // 将标准输入的文件描述符添加到集合fdset中struct timeval tv = {5, 0}; // 定义一个timeval结构体,设置超时时间为5秒int n = select(fd+1, &fdset, NULL, NULL, &tv); // 调用select函数,监视fdset集合中的文件描述符if (-1 == n) // 如果select返回-1,表示发生错误{printf("select err\n"); // 打印错误信息continue; // 继续下一次循环}else if (n == 0) // 如果select返回0,表示超时,没有文件描述符就绪{printf("time out\n"); // 打印超时信息}else // 如果select返回大于0的值,表示有文件描述符就绪{if (FD_ISSET(fd, &fdset)) // 检查标准输入的文件描述符是否就绪{char buff[128] = {0}; // 定义一个字符数组buff,用于存储读取的数据read(fd, buff, 127); // 从标准输入读取数据到buff中,最多读取127个字符printf("read:%s\n", buff); // 打印读取到的数据}}}return 0; // 程序正常结束
}

 

这段代码使用select函数来监视标准输入(键盘输入),并在有输入时读取数据。它首先定义了一个文件描述符集合fdset,并将标准输入的文件描述符添加到这个集合中。然后,它调用select函数来监视这个集合中的文件描述符,等待最多5秒。如果在这5秒内有任何文件描述符就绪(即有输入),select函数会返回就绪的文件描述符的数量。程序然后检查标准输入的文件描述符是否就绪,并从标准输入读取数据。如果5秒内没有文件描述符就绪,select函数会返回0,程序会打印超时信息。如果select函数返回-1,表示发生错误,程序会打印错误信息并继续下一次循环。

  if (FD_ISSET(fd, &fdset)) 

FD_ISSET 是一个宏,用于检查一个特定的文件描述符(FD)是否已经包含在文件描述符集合(fd_set)中。这个宏是在使用 select 函数后,用来确定哪些文件描述符已经准备好进行 I/O 操作(如读、写)的常用方法。

struct timeval tv = {5, 0}; // 定义一个timeval结构体,设置超时时间为5秒

  • struct timeval tv = {5, 0};:定义了一个timeval结构体变量tv,并初始化它。

  • timeval结构体:在Linux中,timeval结构体用于表示时间值,它包含两个字段:

    • tv_sec:表示时间的秒数部分。

    • tv_usec:表示时间的微秒数部分。

  • 初始化:这里将tv_sec初始化为5,tv_usec初始化为0。这意味着超时时间为5秒。 

 2.3 基于 `select` 模型的多客户端 TCP 服务器实现

select.c

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <sys/select.h>
#include <time.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <netinet/in.h>#define MAXFD 10 // 定义最大文件描述符数量// 初始化文件描述符数组
void fds_init(int fds[])
{for (int i = 0; i < MAXFD; i++){fds[i] = -1; // 将所有元素初始化为-1,表示未使用}
}// 向文件描述符数组添加一个文件描述符
void fds_add(int fds[], int fd)
{for (int i = 0; i < MAXFD; i++){if (-1 == fds[i]){fds[i] = fd; // 找到空位,添加文件描述符break; // 添加成功后退出循环}}
}// 从文件描述符数组中删除一个文件描述符
void fds_del(int fds[], int fd)
{for (int i = 0; i < MAXFD; i++){if (fds[i] == fd){fds[i] = -1; // 找到文件描述符,将其删除break; // 删除成功后退出循环}}
}// 初始化套接字
int socket_init()
{int sockfd = socket(AF_INET, SOCK_STREAM, 0); // 创建一个IPv4 TCP套接字if (sockfd == -1){return -1; // 创建失败,返回-1}struct sockaddr_in saddr; // 定义一个sockaddr_in结构体,用于存储服务器地址信息memset(&saddr, 0, sizeof(saddr)); // 将结构体清零saddr.sin_family = AF_INET; // 设置地址族为IPv4saddr.sin_port = htons(6000); // 设置端口号为6000,并转换为网络字节序saddr.sin_addr.s_addr = inet_addr("127.0.0.1"); // 设置IP地址为127.0.0.1int res = bind(sockfd, (struct sockaddr *)&saddr, sizeof(saddr)); // 绑定套接字到本地地址if (-1 == res){printf("bind err\n"); // 绑定失败,打印错误信息return -1; // 返回-1}res = listen(sockfd, 5); // 开始监听连接请求,最多允许5个连接请求排队if (res == -1){return -1; // 监听失败,返回-1}return sockfd; // 返回监听套接字的文件描述符
}// 接受客户端连接请求
void accept_client(int sockfd, int fds[])
{int c = accept(sockfd, NULL, NULL); // 接受一个连接请求if (c < 0){return; // 接受失败,直接返回}printf("accept c=%d\n", c); // 打印接受的客户端文件描述符fds_add(fds, c); // 将客户端文件描述符添加到数组
}// 接收数据
void recv_data(int c, int fds[])
{char buff[128] = {0}; // 定义一个缓冲区,用于存储接收的数据int n = recv(c, buff, 127, 0); // 从客户端接收数据if (n <= 0){close(c); // 关闭套接字fds_del(fds, c); // 从数组中删除客户端文件描述符printf("client close\n"); // 打印客户端关闭信息return; // 返回}printf("recv:%s\n", buff); // 打印接收到的数据send(c, "ok", 2, 0); // 向客户端发送确认信息
}int main()
{int fds[MAXFD]; // 定义一个文件描述符数组fds_init(fds); // 初始化文件描述符数组int sockfd = socket_init(); // 初始化套接字if (sockfd == -1){exit(1); // 初始化失败,退出程序}fds_add(fds, sockfd); // 将监听套接字的文件描述符添加到数组fd_set fdset; // 定义一个文件描述符集合while (1){FD_ZERO(&fdset); // 清空文件描述符集合int maxfd = -1; // 初始化最大文件描述符for (int i = 0; i < MAXFD; i++){if (fds[i] == -1){continue; // 跳过未使用的文件描述符}if (maxfd < fds[i]){maxfd = fds[i]; // 更新最大文件描述符}FD_SET(fds[i], &fdset); // 将文件描述符添加到集合}struct timeval tv = {5, 0}; // 设置超时时间为5秒int n = select(maxfd + 1, &fdset, NULL, NULL, &tv); // 调用select函数,监视文件描述符集合if (-1 == n){printf("select err\n"); // select失败,打印错误信息}else if (0 == n){printf("time out\n"); // 超时,打印超时信息}else{for (int i = 0; i < MAXFD; i++){if (-1 == fds[i]){continue; // 跳过未使用的文件描述符}if (FD_ISSET(fds[i], &fdset)) // 检查文件描述符是否有就绪事件{// 处理就绪的文件描述符if (fds[i] == sockfd){// 监听套接字就绪,接受客户端连接请求accept_client(sockfd, fds);}else{// 客户端套接字就绪,接收数据recv_data(fds[i], fds);}}}}}
}

1. **包含必要的头文件**:
   - 引入标准输入输出、标准库、Unix 系统调用、字符串操作、套接字编程、IP 地址转换等相关的头文件。

2. **定义常量**:
   - 定义 `MAXFD` 常量,表示文件描述符数组的最大长度。

3. **初始化文件描述符数组** (`fds_init` 函数):
   - 遍历数组,将所有元素初始化为 `-1`,表示这些文件描述符当前未被使用。

4. **添加文件描述符到数组** (`fds_add` 函数):
   - 在数组中查找第一个 `-1` 值的位置,并将传入的文件描述符 `fd` 存储在该位置。

5. **从数组中删除文件描述符** (`fds_del` 函数):
   - 在数组中查找传入的文件描述符 `fd`,并将对应的元素设置为 `-1`。

6. **初始化套接字** (`socket_init` 函数):
   - 创建 TCP 套接字。
   - 设置服务器地址结构体 `sockaddr_in`,包括 IP 地址和端口号。
   - 绑定套接字到指定的 IP 地址和端口号。
   - 使套接字开始监听连接请求。

7. **接受客户端连接请求** (`accept_client` 函数):
   - 使用 `accept` 函数接受一个新的客户端连接请求。
   - 打印客户端文件描述符。
   - 将客户端文件描述符添加到文件描述符数组中。

8. **接收数据** (`recv_data` 函数):
   - 从指定的客户端文件描述符接收数据。
   - 如果接收到的数据长度小于等于0(表示客户端已关闭连接),则关闭套接字并从数组中删除对应的文件描述符。
   - 打印接收到的数据,并给客户端发送确认信息。

9. **主函数 (`main`)**:
   - 初始化文件描述符数组。
   - 调用 `socket_init` 函数初始化套接字,并将监听套接字的文件描述符添加到数组中。
   - 进入一个无限循环,持续等待和处理事件:
     - 清空 `fd_set` 结构体 `fdset`。
     - 遍历文件描述符数组,将所有有效的文件描述符添加到 `fdset` 中,并更新 `maxfd` 变量。
     - 设置超时时间。
     - 调用 `select` 函数监视 `fdset` 中的文件描述符,等待最多5秒钟。
     - 根据 `select` 的返回值处理错误、超时或就绪的文件描述符:
       - 如果 `select` 返回 `-1`,表示发生错误,打印错误信息。
       - 如果 `select` 返回 `0`,表示超时,打印超时信息。
       - 如果 `select` 返回大于 `0` 的值,表示有文件描述符就绪,遍历文件描述符数组,检查哪些文件描述符有就绪事件,并进行相应的处理:
         - 如果就绪的文件描述符是监听套接字,则调用 `accept_client` 函数接受新的客户端连接请求。
         - 如果就绪的文件描述符是客户端套接字,则调用 `recv_data` 函数接收数据。

通过这些步骤,服务器能够同时处理多个客户端连接请求和数据接收,实现高效的 I/O 复用。

这段代码实现了一个简单的TCP服务器,它使用 select 函数来同时处理多个客户端连接请求和数据接收。服务器首先初始化一个监听套接字,并将其文件描述符添加到文件描述符数组中。然后,它进入一个无限循环,使用 select 函数监视文件描述符数组中的所有文件描述符。当有文件描述符就绪时,服务器会根据文件描述符的类型(监听套接字或客户端套接字)来处理相应的事件(接受连接请求或接收数据)。 

cli.c

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <netinet/in.h>int main()
{int sockfd = socket(AF_INET, SOCK_STREAM, 0); // 创建一个IPv4 TCP套接字if (sockfd == -1) // 检查套接字创建是否成功{exit(1); // 如果失败,退出程序}struct sockaddr_in saddr; // 定义一个sockaddr_in结构体,用于存储服务器地址信息memset(&saddr, 0, sizeof(saddr)); // 将结构体清零saddr.sin_family = AF_INET; // 设置地址族为IPv4saddr.sin_port = htons(6000); // 设置端口号为6000,并转换为网络字节序saddr.sin_addr.s_addr = inet_addr("127.0.0.1"); // 设置IP地址为127.0.0.1int res = connect(sockfd, (struct sockaddr*)&saddr, sizeof(saddr)); // 连接到服务器if (res == -1) // 检查连接是否成功{printf("connect err\n"); // 如果失败,打印错误信息exit(1); // 退出程序}while (1) // 无限循环,持续发送和接收数据{printf("input\n"); // 提示用户输入char buff[128] = {0}; // 定义一个缓冲区,用于存储输入和接收的数据fgets(buff, 128, stdin); // 从标准输入读取一行数据if (strncmp(buff, "end", 3) == 0) // 检查是否输入了"end"命令{break; // 如果是,退出循环}send(sockfd, buff, strlen(buff) - 1, 0); // 发送数据到服务器,不包括换行符memset(buff, 0, 128); // 清空缓冲区recv(sockfd, buff, 127, 0); // 从服务器接收数据printf("read:%s\n", buff); // 打印接收到的数据}close(sockfd); // 关闭套接字exit(0); // 程序正常结束
}

 这段代码实现了一个简单的TCP客户端,它连接到本地服务器(127.0.0.1:6000),并持续发送和接收数据。用户可以在命令行中输入数据,输入"end"命令时,程序会退出。

相关文章:

I/O复用函数的使用——select

I/O复用函数的使用——select 目录 一、概念 二、select接口 2.1 基础概念 2.2 使用 select 函数的标准输入读取代码 2.3 基于 select 模型的多客户端 TCP 服务器实现 一、概念 i/o复用使得程序能同时监听多个文件描述符&#xff0c;可以提高程序性能。 之前为了让服务器能…...

LangChain与图数据库Neo4j LLMGraphTransformer融合:医疗辅助诊断、金融风控领域垂直领域、法律咨询场景问答系统的技术实践

LangChain与图数据库融合&#xff1a;垂直领域问答系统的技术实践 一、技术背景与核心价值 在垂直领域&#xff08;如金融、医疗、法律&#xff09;的问答场景中&#xff0c;传统RAG系统常面临实体关系推理不足和专业术语理解偏差的痛点。LangChain通过集成图数据库与知识图谱…...

Trae国际版的下载与简单使用示例(免费使用Claude,GPT4.1等多个高级模型)

文章目录 Trae的下载与使用什么是Trae重要亮点Trae的核心功能主要特点 安装指南下载步骤系统要求安装步骤 基础操作代码补全代码生成代码解释 高级功能自定义设置 总结参考资料 Trae的下载与使用 什么是Trae Trae是一款先进的AI编程助手工具&#xff0c;专为开发者打造。它集…...

Python 金融量化分析

文章目录 1. IPython&#xff1a;交互式的 Python 命令行安装常用操作IPython Notebook 2. NumPy&#xff1a;数据计算模块主要功能安装与导入创建 ndarrayndarray 的常用属性示例代码常用创建函数示例代码 3. NumPy 索引和切片数组运算数组索引和切片布尔型索引花式索引通用函…...

Linux:进程:进程控制

进程创建 在Linux中我们使用fork函数创建新进程&#xff1a; fork函数 fork函数是Linux中的一个系统调用&#xff0c;用于创建一个新的进程&#xff0c;创建的新进程是原来进程的子进程 返回值&#xff1a;如果子进程创建失败&#xff0c;返回值是-1。如果子进程创建成功&a…...

量子计算在金融领域的应用与展望

在当今数字化时代&#xff0c;金融行业正面临着前所未有的技术变革。量子计算作为前沿科技领域的明珠&#xff0c;正在逐渐从实验室走向实际应用&#xff0c;为金融行业带来新的机遇和挑战。本文将探讨量子计算在金融领域的应用现状、优势以及未来的发展展望。 一、量子计算简介…...

StarRocks:一款开源的高性能分析型数据仓库

StarRocks 是一款高性能分析型数据仓库&#xff0c;使用向量化、MPP 架构、CBO&#xff08;基于成本优化&#xff09;、智能物化视图、可实时更新的列式存储引擎等技术实现多维、实时、高并发的数据分析。 StarRocks 是一个 Linux 基金会开源项目&#xff0c;采用 Apache 2.0 许…...

NLP高频面试题(四十九)大模型RAG常见面试题解析

为什么要构建RAG系统? RAG系统通过结合信息检索和生成模型,解决了LLM在知识更新、幻觉和上下文限制等方面的挑战。它允许模型在生成响应前引用外部知识库,提高答案的准确性和相关性。 RAG与大模型微调的区别? 项目RAG系统大模型微调知识更新通过更新外部知识库实现需要重…...

【NLP 68、R-BERT】

为什么划掉你的名字&#xff0c;为什么不敢与你对视 —— 25.4.21 一、R-BERT&#xff1a;基于BERT的关系抽取模型 R-BERT&#xff08;Relation BERT&#xff09;是一种用于关系抽取&#xff08;Relation Extraction&#xff09;任务的模型&#xff0c;它结合了预训练语言模型…...

Java:多线程

多线程 线程是操作系统能够进行运算调度的最小单位。它被包含在进程之中&#xff0c;是进程中的实际运作单位。 并发和并行 并发&#xff1a;在同一时刻&#xff0c;有多个指令在单个CPU上交替执行 并行&#xff1a;在同一时刻&#xff0c;有多个指令在多个CPU上同时执行 …...

第一章:自然语言处理

目录 1.1 自然语言处理发展史 1.2 统计语言模型发展史 统计语言模型 NNLM 模型 Word2Vec 模型 ELMo 模型 BERT 模型 大语言模型 1.3 小结 自然语言处理&#xff08;Natural Language Processing&#xff0c;NLP&#xff09;是一门借助计算机技术研究人类语言的科学。虽…...

Git 大文件使用 Git-LFS 管理,推送失败

配置了.gitattributes文件后&#xff0c; *.jar filterlfs difflfs mergelfs -text *.so filterlfs difflfs mergelfs -text *.aar filterlfs difflfs mergelfs -text *.bin filterlfs difflfs mergelfs -text *.a filterlfs difflfs mergelfs -text 仍然推送失败 POST git-…...

[c语言日寄]免费文档生成器——Doxygen在c语言程序中的使用

【作者主页】siy2333 【专栏介绍】⌈c语言日寄⌋&#xff1a;这是一个专注于C语言刷题的专栏&#xff0c;精选题目&#xff0c;搭配详细题解、拓展算法。从基础语法到复杂算法&#xff0c;题目涉及的知识点全面覆盖&#xff0c;助力你系统提升。无论你是初学者&#xff0c;还是…...

RK3588上编译opencv 及基于c++实现图像的读入

参考博文&#xff1a; https://blog.csdn.net/qq_47432746/article/details/147203889 一、安装依赖包 sudo apt install build-essential cmake git pkg-config libgtk-3-dev libavcodec-dev libavformat-dev libswscale-dev libv4l-dev libxvidcore-dev libx264-dev libjpe…...

C++ GPU并行计算开发实战:利用CUDA/OpenCL加速粒子系统与流体模拟

&#x1f9d1; 博主简介&#xff1a;CSDN博客专家、CSDN平台优质创作者&#xff0c;高级开发工程师&#xff0c;数学专业&#xff0c;10年以上C/C, C#, Java等多种编程语言开发经验&#xff0c;拥有高级工程师证书&#xff1b;擅长C/C、C#等开发语言&#xff0c;熟悉Java常用开…...

Java 设计模式心法之第3篇 - 总纲:三大流派与导航地图

前两章&#xff0c;我们修炼了 SOLID 这套强大的“内功心法”&#xff0c;为构建高质量软件打下了坚实根基。现在&#xff0c;是时候鸟瞰整个设计模式的“武林”了&#xff01;本文将为您展开一幅由 GoF 四人帮精心绘制的 23 种经典设计模式的“全景导航地图”。我们将探索这些…...

高级java每日一道面试题-2025年4月19日-微服务篇[Nacos篇]-Nacos未来的发展方向和规划有哪些?

如果有遗漏,评论区告诉我进行补充 面试官: Nacos未来的发展方向和规划有哪些&#xff1f; 我回答: Nacos 作为阿里巴巴开源的服务发现、配置管理和服务治理平台&#xff0c;其未来的发展方向和规划主要体现在以下几个关键领域&#xff1a; 1. 安全性与标准化 API分类精细化…...

跳过reCAPTCHA验证的技术解析与优化实践

Google的reCAPTCHA验证系统已成为保护网站安全的核心工具之一。然而&#xff0c;频繁的验证弹窗可能降低用户体验&#xff0c;甚至导致用户流失。如何在遵守平台规则的前提下&#xff0c;通过技术优化与用户行为管理减少验证触发率&#xff0c;成为我们亟需解决的难题。 但需要…...

idea使用docker插件一键部署项目

一、首先保证我们电脑上已经安装了docker docker -v查看docker版本&#xff0c;如果不能识别&#xff0c;需要先下载docker destop&#xff0c;在官网下载正常安装即可。 安装成功就可以使用docker 命令了 二、idea下载docker插件并配置docker参数 我是通过tcp连接docker服务…...

强化学习笔记(三)——表格型方法(蒙特卡洛、时序差分)

强化学习笔记&#xff08;三&#xff09;——表格型方法&#xff08;蒙特卡洛、时序差分&#xff09; 一、马尔可夫决策过程二、Q表格三、免模型预测1. 蒙特卡洛策略评估1) 动态规划方法和蒙特卡洛方法的差异 2. 时序差分2.1 时序差分误差2.2 时序差分方法的推广 3. 自举与采样…...

[SpringMVC]请求响应参数传递

controller前置url解决业务重名 在项目中&#xff0c;常常会碰到不同的业务之间的某个方法同名的情况。例如在一个文档管理系统&#xff08;有着文档和发布者两个实体&#xff09;中&#xff0c;两个实体都有着 "add" 业务。如果两个实体相关的业务url都用 "/ad…...

在C++业务类和QML之间创建一个数据桥梁

工作中经常会遇到两种业务直接按无法直接沟通&#xff0c;此时需要建立一个桥梁将两者进行联系起来&#xff0c;假设一个C业务类&#xff0c;有一个QML UI&#xff0c; 如果将BridgeClass 类通过qmlRegisterType 注册到QML中&#xff0c;在C中如何能够调用到BridgeClass 对象吗…...

超详细mac上用nvm安装node环境,配置npm

一、安装NVM 打开终端&#xff0c;运行以下命令来安装NVM&#xff1a; curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.5/install.sh | bash 然后就会出现如下代码&#xff1a; > Profile not found. Tried ~/.bashrc, ~/.bash_profile, ~/.zprofile, ~/.…...

MH2103系列coremark1.0跑分数据和优化,及基于arm2d的优化应用

CoreMark 1.0 介绍 CoreMark 是由 EEMBC&#xff08;Embedded Microprocessor Benchmark Consortium&#xff09;组织于 2009 年推出的一款用于衡量嵌入式系统 CPU 或 MCU 性能的标准基准测试工具。它旨在替代陈旧的 Dhrystone 标准&#xff08;Dhrystone 容易受到各种libc不同…...

YOLO11改进 | 特征融合Neck篇之Lowlevel Feature Alignment机制:多尺度检测的革新性突破

## 为什么需要重新设计特征融合机制? 在目标检测领域,YOLO系列模型因其高效的实时性成为工业界和学术界的标杆。然而,随着应用场景的复杂化(如自动驾驶中的多尺度目标、无人机图像中的小物体检测),传统特征融合策略的局限性逐渐暴露:**特征对齐不足导致语义信息错位、多…...

解决方案:远程shell连不上Ubuntu服务器

服务器是可以通过VNC登录&#xff0c;排除了是服务器本身故障 检查服务是否在全网卡监听 sudo ss -tlnp | grep sshd确保有一行类似 LISTEN 0 128 0.0.0.0:22 0.0.0.0:* users:(("sshd",pid...,fd3))返回无结果&#xff0c;表明系统里并没有任…...

Flutter路由模块化管理方案

总结记录一下Flutter路由模块管理&#xff1a; 1、创建路由基类 abstract class BaseRouteConfig {Map<String, WidgetBuilder> get routes; } 2、创建不同模块的路由配置类 // 认证模块路由 class AuthRoutes extends BaseRouteConfig {overrideMap<String, Widg…...

Java BIO、NIO、AIO、Netty面试题(已整理全套PDF版本)

什么是IO Java中的I/O&#xff08;输入/输出&#xff09;机制基于流&#xff08;Stream&#xff09;的概念实现数据的传输。流将数据序列化&#xff0c;即按照特定顺序逐次进行读写操作。简而言之&#xff0c;Java程序通过I/O流与外部设备进行数据交换。 Java类库中的I/O功能十…...

TapData × 梦加速计划 | 与 AI 共舞,TapData 携 AI Ready 实时数据平台亮相加速营,企业数据基础设施现代化

在实时跃动的数据节拍中&#xff0c;TapData 与 AI 共舞&#xff0c;踏出智能未来的新一步。 4月10日&#xff0c;由前海产业发展集团、深圳市前海梦工场、斑马星球科创加速平台等联合发起的「梦加速计划下一位独角兽营」正式启航。 本次加速营以“打造下一位独角兽企业”为目…...

一键部署k8s之EFK日志收集系统

一、部署es 1.下载安装 #下载安装 https://artifacts.elastic.co/downloads/elasticsearch/elasticsearch-8.13.2-linux-x86_64.tar.gz #解压 [rootes software]# tar xf elasticsearch-8.13.2-linux-x86_64.tar.gz #创建运行elasticsearch服务用户并修改权限 [rootes softw…...

Python常用的第三方模块【openpyxl库】读写Excel文件

openpyxl库模块是用于处理Microsoft Excel文件的第三方库&#xff0c;可以对Excel文件中的数据进行写入和读取。 weather.pyimport reimport requests#定义函数 def get_html():urlhttps://www.weather.com.cn/weather1d/101210101.shtml #爬虫打开浏览器上的网页resprequests.…...

加油站小程序实战教程12显示会员信息

目录 1 布局搭建1.1 搭建头像1.2 显示会员等级1.3 余额显示 最终效果 我们上一篇介绍了会员注册的功能&#xff0c;会员注册后再次进入页面的时候就可以根据openid加载会员信息&#xff0c;本篇我们介绍一下显示会员的余额 1 布局搭建 我们现在在我的页面显示的是会员未开通…...

iOS中使用AWS上传zip文件到Minio上的oss平台上

1. 集成AWS相关库&#xff08;千万不要用最新的版本&#xff0c;否则会出现风格化虚拟路径&#xff0c;找不到主机名&#xff09; pod AWSS3, ~> 2.10.0 pod AWSCore, ~> 2.10.0 2. 编写集成的相关代码 - (void)uploadFileToMinIO {NSString *endPoint "http://…...

PaginationInnerInterceptor使用(Mybatis-plus分页)

引言 最近在编写SQL语句时总是想着偷懒&#xff0c;于是在前不久学习黑马点评时学到可以使用PaginationInnerInterceptor&#xff0c;于是现在我也在自己的项目中进行使用了&#xff0c;但是使用也遇到一些问题&#xff0c;如果你和我的问题一样&#xff0c;希望我的解决办法能…...

极狐GitLab CEO 柳钢受邀出席 2025 全球机器学习技术大会

极狐GitLab 是 GitLab 在中国的发行版&#xff0c;关于中文参考文档和资料有&#xff1a; 极狐GitLab 中文文档极狐GitLab 中文论坛极狐GitLab 官网 2025 年 4 月 18 日至 19 日&#xff0c;2025 全球机器学习技术大会&#xff08;ML-Summit 2025&#xff09;在上海隆重举行。…...

数据仓库 vs 数据湖:架构、应用场景与技术差异全解析

目录 一、概念对比&#xff1a;结构化 vs 全类型数据 二、技术架构对比 1. 数据仓库架构特点 2. 数据湖架构特点 三、典型应用场景 数据仓库适合&#xff1a; 数据湖适合&#xff1a; 四、数据湖仓一体&#xff1a;趋势还是折中&#xff1f; 五、总结&#xff1a;如何…...

【25软考网工笔记】第三章 局域网(1)CSMA/CD、二进制指数退避算法、最小帧长计算

目录 一、CSMA/CD 1. 局域网架构概述 2. 局域网的拓扑结构 3. CSMA 1&#xff09;CSMA的三种监听算法 1、1-坚持型监听算法&#xff08;继续监听&#xff0c;不等待&#xff09; 2、非坚持型监听算法&#xff08;后退随机事件&#xff09; 3、P-坚持型监听算法 2&#…...

Harbor对接非AWS对象存储

背景说明 项目的应用完全运行在一个离线环境中&#xff0c;同时通过K8S的方式进行容器编排。需要自建一个harbor的镜像仓库。并且通过私有云提供的S3服务进行容器镜像的持久化存储。我踩的其中的一个坑就是S3的region名字非AWS的标准名称。运行时抱错如下&#xff1a; 2025-04…...

实训Day-1 漏洞攻击实战

目录 实训任务1 漏洞攻击实战一 实训任务2 漏洞攻击实战二 实训任务3 白云新闻搜索 实训任务4 手速要快 实训任务5 包罗万象 总结 今天的实训目的是为了&#xff1a;了解漏洞攻击的一般步骤&#xff1b;掌握SQL注入的基本原理&#xff1b;掌握XSS攻击的基本原理&#xff…...

Linux-网络基础

一.网络背景 网络的起源与20世纪中期的冷战背景密切相关。美苏争霸期间&#xff0c;美国国防部担心传统集中式通信系统&#xff08;如电话网络&#xff09;在核战争中容易被摧毁&#xff0c;因此急需一种去中心化、高容错的通信方式。1969年&#xff0c;美国国防部高级研究计划…...

算法 | 鲸鱼优化算法(WOA)原理,公式,应用,算法改进研究综述,完整matlab代码

===================================================== github:https://github.com/MichaelBeechan CSDN:https://blog.csdn.net/u011344545 ===================================================== 鲸鱼优化算法 一、原理与公式二、应用领域三、算法改进研究四、完整MAT…...

[BJDCTF2020]EzPHP

这一道题里面的知识点实在是太多了&#xff0c;即使这道题是我最喜欢的RCE也有点大脑停转了&#xff0c;所以还是做个笔记&#xff0c;以后方便回忆 直接跳过打点&#xff0c;来到源码 <?php highlight_file(__FILE__); error_reporting(0); $file "1nD3x.php"…...

企业微信-自建应用

1. 创建自建应用 2. 配置小程序/H5入口 3. 准备 &#xff1a; CorpId&#xff08;企业id&#xff09;、 AgentID&#xff08;应用id&#xff09;、 CorpsecretID&#xff08;应用Secret&#xff09; 4. 配置企业可信IP 5. 如H5需要授权登录&#xff0c;那么需要配置网页授…...

[FPGA基础] 时钟篇

Xilinx FPGA 时钟管理详细文档 本文档详细介绍 Xilinx FPGA 中的时钟管理&#xff0c;包括时钟资源、时钟管理模块、设计注意事项以及最佳实践。适用于使用 Xilinx 7 系列、UltraScale 和 UltraScale 系列 FPGA 的开发者。 1. 时钟资源概述 Xilinx FPGA 提供丰富的时钟资源&a…...

高德火星坐标(GCJ-02)转WGS84坐标

高德火星坐标(GCJ-02)转WGS84坐标 1 转换算法 import mathdef gcj02_to_wgs84(lon, lat):"""高德火星坐标(GCJ-02)转WGS84坐标"""a 6378245.0 # 长半轴ee 0.00669342162296594323 # 扁率def transform_lon(x, y):ret 300.0 x 2.0 * y …...

基于opencv和PaddleOCR识别身份证信息

1、安装组件 pip install --upgrade paddlepaddle paddleocr 2、完整code import cv2 import numpy as np from paddleocr import PaddleOCR# 初始化 PaddleOCR use_angle_clsTrue, lang"ch", det_db_thresh0.1, det_db_box_thresh0.5)def preprocess_image(image…...

Day-1 漏洞攻击实战

实训任务1 漏洞攻击实战一 使用 御剑 得到网站后台地址 数据库登录与日志配置​​ 使用默认密码 root:root 登录phpMyAdmin&#xff0c;执行 SHOW VARIABLES LIKE general% 查看日志状态。 开启日志功能&#xff1a;set global general_log "ON";&#xff08;配图&…...

穿透数据迷雾:PR 曲线与 ROC 曲线的深度剖析+面试常见问题及解析

一、混淆矩阵与评价指标基础 混淆矩阵核心构成&#xff1a;混淆矩阵是分类模型性能评估的基石&#xff0c;以 22 矩阵形式呈现分类结果。其中&#xff0c;真正例&#xff08;TP&#xff09;表示实际为正类且被正确预测的样本&#xff1b;假正例&#xff08;FP&#xff09;是实…...

【Linux篇】轻松搭建命名管道通信:客户端与服务器的互动无缝连接

从零开始&#xff1a;基于命名管道实现客户端与服务器的实时通信 一. 命名管道1.1 基本概念1.2 创建命名管道1.2.1 创建方法1.2.2 示例代码&#xff1a;1.2.3 注意事项&#xff1a;1.3 与匿名管道区别 1.4 打开原则1.4.1 管道打开顺序1.4.2 阻塞行为1.4.3 管道的关闭1.4.4 关闭…...

快充协议芯片XSP04D支持使用一个Type-C与电脑传输数据和快充取电功能

快充是由充电器端的充电协议和设备端的取电协议进行握手通讯进行协议识别来完成的&#xff0c;当充电器端的充电协议和设备端的取电协议握手成功后&#xff0c;设备会向充电器发送电压请求&#xff0c;充电器会根据设备的需求发送合适的电压给设备快速供电。 设备如何选择快充…...