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

Linux系统篇——文件描述符FD

🧠 Linux 文件描述符(File Descriptor)详解与学习指南


一、什么是文件描述符(fd)

在 Linux 中,一切皆文件(everything is a file),包括普通文件、目录、套接字(socket)、管道(pipe)、设备文件等。

文件描述符(File Descriptor, fd) 是一个非负整数,是 Linux 为每个打开的文件或资源分配的索引号,用于在内核中标识和操作打开的文件对象。


二、标准文件描述符

Linux 启动一个进程时,会默认打开三个文件描述符:

文件描述符名称作用
0stdin标准输入(键盘)
1stdout标准输出(终端)
2stderr标准错误输出(终端)

三、文件描述符的分配机制

  1. 文件描述符是按顺序从最小的可用整数分配的。
  2. 每个进程都有自己的文件描述符表,是进程私有的。
  3. 文件描述符表中的每个项指向一个文件表项(File Table Entry),其中包含文件偏移量、访问模式等。
  4. 文件表项再指向VFS I节点(与具体文件绑定)。

✅ 这三层结构:文件描述符表文件表项inode(VFS)


四、相关系统调用

1. 打开/关闭文件

int open(const char *pathname, int flags);       // 返回 fd
int open(const char *pathname, int flags, mode_t mode);
int close(int fd);                               // 关闭文件描述符

2. 读写文件

ssize_t read(int fd, void *buf, size_t count);   // 从fd读取数据
ssize_t write(int fd, const void *buf, size_t count); // 向fd写数据

3. 文件描述符复制

int dup(int oldfd);          // 复制fd,返回新的最小可用fd
int dup2(int oldfd, int newfd); // 精确复制fd到newfd上
int dup3(int oldfd, int newfd, int flags); // 带flag控制

五、文件描述符的高级操作

1. 重定向

command > file.txt     # stdout 重定向
command < input.txt    # stdin 重定向
command 2> err.txt     # stderr 重定向
command &> all.txt     # stdout 和 stderr 同时重定向

也可以在 C 中重定向:

int fd = open("output.txt", O_WRONLY | O_CREAT, 0644);
dup2(fd, 1); // 将stdout重定向到fd

2. 非阻塞 IO 设置

int flags = fcntl(fd, F_GETFL, 0);
fcntl(fd, F_SETFL, flags | O_NONBLOCK);  // 设置非阻塞

六、查看进程打开的文件描述符

ls /proc/<pid>/fd/

也可以用 lsof -p <pid> 查看详细信息。


七、文件描述符泄漏与管理

常见问题:

  • 打开文件未及时 close,导致资源泄漏。
  • 子进程继承父进程的 fd,造成 文件句柄泄漏
  • 文件描述符耗尽:系统或进程达到 fd 打开数量上限(默认 1024)

设置进程最大文件描述符数

ulimit -n 65535

八、实际应用场景

  • 网络编程中 socket 使用 fd
  • 多路复用(select, poll, epoll)基于 fd
  • 管道、重定向、子进程通信均依赖 fd
  • 内核态-用户态资源管理

九、调试和监控工具

工具用途
lsof查看进程打开的文件
strace跟踪系统调用,观察 fd 使用
/proc/<pid>/fd查看指定进程文件描述符

🔚 总结

特性内容
定义fd 是对打开文件的标识索引
范围一般为非负整数,进程私有
用途文件、网络、设备、IPC 等操作
管理合理使用 close/dup/ulimit 等机制

嵌入式设备(尤其是运行 Linux 的嵌入式系统)中,文件描述符(fd)管理 是资源管理中的核心内容之一。因为资源有限(内存小、文件系统简化、线程少等),fd 使用必须更加谨慎、合理。

📟 嵌入式设备上的 fd 管理详解


一、嵌入式环境下的 fd 特点

特点描述
资源有限文件描述符数量小(常见为 ulimit -n 64 或更低)
文件类型多样普通文件、设备文件、socket、管道等都依赖 fd
常驻服务进程多比如 watchdog、通信服务、日志服务,fd 泄漏易积累
稳定性要求高fd 泄漏可能引起系统死锁或重启,不能容忍崩溃

二、常见 fd 使用场景(嵌入式)

场景描述
UART/串口通信打开 /dev/ttyS* 获取 fd,收发数据
网络通信使用 socket 返回的 fd 读写数据
IO 控制设备open("/dev/xxx") + ioctl() 控制硬件
日志输出写文件或通过网络/串口输出日志
管道通信父子进程或线程间通信依赖 fd 管道
epoll/select/poll多路复用高效管理多个 IO 设备

三、fd 使用示例(嵌入式通信)

示例:串口通信(串口为 /dev/ttyS1

int fd = open("/dev/ttyS1", O_RDWR | O_NOCTTY | O_NONBLOCK);
if (fd < 0) {perror("open");return -1;
}
// 配置串口参数略
write(fd, "hello", 5);   // 发送数据
read(fd, buf, 100);       // 接收数据
close(fd);                // 必须释放

四、fd 泄漏问题与监控手段

1. 常见原因

  • 打开文件/设备后忘记 close
  • 多线程重复打开但未共享/回收 fd
  • 子进程未清理继承的 fd
  • 线程/进程异常退出未清理 fd

2. 检查方法

  • 查看 /proc/<pid>/fd/
  • 使用 lsof -p <pid>
  • 增加代码层日志打印:打开/关闭 fd 时打印日志
  • 使用 valgrind 检查资源泄露(如适用于开发阶段)

五、fd 复用与最大限制优化

1. 降低 fd 数量开销的方式

  • 长连接共享 fd(例如:UART 只初始化一次,线程共享)
  • fd 池化:维护打开的 fd 池,避免重复打开
  • epoll/select 合理使用 IO 多路复用,避免线程 per fd 模式

2. 增加 fd 限制(需内核支持)

临时提升限制:

ulimit -n 512

程序内:

#include <sys/resource.h>
struct rlimit rl;
rl.rlim_cur = 512;
rl.rlim_max = 512;
setrlimit(RLIMIT_NOFILE, &rl);

注意:嵌入式系统需要 root 权限且内核配置允许


六、fd 管理最佳实践(嵌入式专属)

建议描述
封装 open/close 接口统一记录日志、错误码处理,便于排查问题
加入 fd 泄漏检测机制启动时检测打开文件数量,定期检查 fd 使用量
定期巡检 fd 表定时读取 /proc/self/fd 判断是否异常增长
所有打开动作均加错误判断包括 open/socket/accept 等,避免异常触发崩溃
使用 epoll/poll 管理高并发 fd尤其适合小资源高效率处理设备数据
子进程创建前清理 fd使用 FD_CLOEXEC 或手动关闭无用 fd
异常退出时做清理信号处理器中注册清理动作,确保 fd 不悬挂

七、常见陷阱

场景错误现象
没有设置 O_NONBLOCK串口或 socket 阻塞,线程卡死
多线程使用同一 fd 无锁保护串口数据错乱或丢失
accept 后未 closefd 泄漏,连接数逐渐耗尽
子进程继承父 fd意外重用已关闭 fd,产生不可预期行为
fd 重复打开造成重复资源消耗且无警告

八、可选工具与方案

工具/技术功能
valgrind --leak-check=full检查内存/资源泄漏
lsof / fuser检查 fd 占用
strace跟踪 open/read/write/close 系统调用
procfs(如 /proc/self/fd/动态查看当前进程 fd

🧠 总结

类别要点
管理方式合理打开、及时关闭、使用 fd 池化
泄漏检查周期性监控 /proc,记录每次 fd 分配
性能优化使用 epoll,避免创建多线程 per fd
系统设置合理设定 ulimit,避免 fd 耗尽问题
稳定性保障异常退出、信号退出前清理 fd,防止死锁或资源不释放

对嵌入式系统的 文件描述符(fd)管理封装代码fd 泄漏检测模块实现,目标是提高资源使用可控性、稳定性和排错效率。


🛠️ 一、fd 管理封装模块(fd_manager.c/.h)

✅ 设计目标:

  • 封装 open/close/dup 等系统调用
  • 自动记录和追踪 fd 状态
  • 支持日志输出和自动清理

📄 fd_manager.h

#ifndef FD_MANAGER_H
#define FD_MANAGER_H#include <stdio.h>#define MAX_TRACKED_FD 1024typedef struct {int fd;char tag[64];   // 用于标识fd用途,比如"log", "uart0"char file[128]; // 打开时的文件名
} FDTrack;int tracked_open(const char *pathname, int flags, const char *tag);
int tracked_open_mode(const char *pathname, int flags, mode_t mode, const char *tag);
int tracked_close(int fd);
void fd_manager_dump(void);              // 打印当前已打开的 fd
void fd_manager_cleanup_all(void);      // 程序退出时自动关闭所有 fd#endif

📄 fd_manager.c

#include "fd_manager.h"
#include <fcntl.h>
#include <string.h>
#include <unistd.h>
#include <stdlib.h>static FDTrack fd_table[MAX_TRACKED_FD];static void track_fd(int fd, const char *pathname, const char *tag) {if (fd < 0 || fd >= MAX_TRACKED_FD) return;fd_table[fd].fd = fd;snprintf(fd_table[fd].file, sizeof(fd_table[fd].file), "%s", pathname);snprintf(fd_table[fd].tag, sizeof(fd_table[fd].tag), "%s", tag);
}static void untrack_fd(int fd) {if (fd < 0 || fd >= MAX_TRACKED_FD) return;fd_table[fd].fd = -1;fd_table[fd].file[0] = '\0';fd_table[fd].tag[0] = '\0';
}int tracked_open(const char *pathname, int flags, const char *tag) {int fd = open(pathname, flags);if (fd >= 0) track_fd(fd, pathname, tag);return fd;
}int tracked_open_mode(const char *pathname, int flags, mode_t mode, const char *tag) {int fd = open(pathname, flags, mode);if (fd >= 0) track_fd(fd, pathname, tag);return fd;
}int tracked_close(int fd) {int ret = close(fd);if (ret == 0) untrack_fd(fd);return ret;
}void fd_manager_dump(void) {printf(">> Opened FD List:\n");for (int i = 0; i < MAX_TRACKED_FD; i++) {if (fd_table[i].fd >= 0) {printf("  [fd=%d] tag=%s file=%s\n", fd_table[i].fd, fd_table[i].tag, fd_table[i].file);}}
}void fd_manager_cleanup_all(void) {for (int i = 0; i < MAX_TRACKED_FD; i++) {if (fd_table[i].fd >= 0) {close(fd_table[i].fd);untrack_fd(i);}}
}

🔧 使用示例:

#include "fd_manager.h"int main() {int uart_fd = tracked_open("/dev/ttyS1", O_RDWR, "uart0");if (uart_fd < 0) {perror("UART open failed");return 1;}int log_fd = tracked_open_mode("log.txt", O_CREAT | O_WRONLY, 0644, "log");write(log_fd, "hello fd\n", 9);fd_manager_dump();  // 打印当前打开的 fdtracked_close(log_fd);tracked_close(uart_fd);return 0;
}

🕵️‍♂️ 二、fd 泄漏检测模块实现

🧩 方法一:通过 /proc/self/fd 定期检查 fd 增长

#include <stdio.h>
#include <dirent.h>
#include <unistd.h>int count_open_fds() {DIR *dir = opendir("/proc/self/fd");if (!dir) return -1;int count = 0;struct dirent *entry;while ((entry = readdir(dir))) {// 排除 . 和 ..if (entry->d_name[0] == '.') continue;count++;}closedir(dir);return count;
}void monitor_fd_leaks() {static int prev_count = -1;int current = count_open_fds();if (current >= 0) {if (prev_count >= 0 && current > prev_count) {printf("⚠️ Warning: FD count increased from %d to %d\n", prev_count, current);}prev_count = current;}
}

🔁 建议定期调用:

while (1) {monitor_fd_leaks();   // 每隔5秒检测一次sleep(5);
}

✅ 总结

组件作用
fd_manager 模块封装 open/close,自动记录 fd 来源、状态
fd 泄漏检测动态比较 /proc/self/fd,发现异常增长
实用价值对嵌入式通信程序、守护进程、串口调试程序特别有用

线程安全版本的 fd 管理封装模块,适用于嵌入式 Linux 多线程环境(如 POSIX 线程)。它在原有的 fd_manager 基础上加入了互斥锁保护,确保多个线程同时操作文件描述符时不会引发数据竞态或管理混乱。


🧵 线程安全 fd 管理模块(fd_manager_threadsafe.c/.h)

🔐 使用 pthread_mutex_t 加锁保护 fd_table 的读写

📄 fd_manager_threadsafe.h

#ifndef FD_MANAGER_THREADSAFE_H
#define FD_MANAGER_THREADSAFE_H#include <stdio.h>
#include <fcntl.h>
#include <sys/types.h>#define MAX_TRACKED_FD 1024typedef struct {int fd;char tag[64];   // 用于标记用途char file[128]; // 打开路径
} FDTrack;int tracked_open(const char *pathname, int flags, const char *tag);
int tracked_open_mode(const char *pathname, int flags, mode_t mode, const char *tag);
int tracked_close(int fd);
void fd_manager_dump(void);              // 打印当前 fd 状态
void fd_manager_cleanup_all(void);      // 程序退出时清理所有 fd
void fd_manager_init(void);             // 初始化(必须调用一次)
void fd_manager_deinit(void);           // 销毁(程序退出前调用)#endif

📄 fd_manager_threadsafe.c

#include "fd_manager_threadsafe.h"
#include <string.h>
#include <unistd.h>
#include <stdlib.h>
#include <pthread.h>static FDTrack fd_table[MAX_TRACKED_FD];
static pthread_mutex_t fd_table_lock;void fd_manager_init(void) {pthread_mutex_init(&fd_table_lock, NULL);for (int i = 0; i < MAX_TRACKED_FD; i++) {fd_table[i].fd = -1;}
}void fd_manager_deinit(void) {fd_manager_cleanup_all();pthread_mutex_destroy(&fd_table_lock);
}static void track_fd(int fd, const char *pathname, const char *tag) {if (fd < 0 || fd >= MAX_TRACKED_FD) return;pthread_mutex_lock(&fd_table_lock);fd_table[fd].fd = fd;snprintf(fd_table[fd].file, sizeof(fd_table[fd].file), "%s", pathname);snprintf(fd_table[fd].tag, sizeof(fd_table[fd].tag), "%s", tag);pthread_mutex_unlock(&fd_table_lock);
}static void untrack_fd(int fd) {if (fd < 0 || fd >= MAX_TRACKED_FD) return;pthread_mutex_lock(&fd_table_lock);fd_table[fd].fd = -1;fd_table[fd].file[0] = '\0';fd_table[fd].tag[0] = '\0';pthread_mutex_unlock(&fd_table_lock);
}int tracked_open(const char *pathname, int flags, const char *tag) {int fd = open(pathname, flags);if (fd >= 0) track_fd(fd, pathname, tag);return fd;
}int tracked_open_mode(const char *pathname, int flags, mode_t mode, const char *tag) {int fd = open(pathname, flags, mode);if (fd >= 0) track_fd(fd, pathname, tag);return fd;
}int tracked_close(int fd) {int ret = close(fd);if (ret == 0) untrack_fd(fd);return ret;
}void fd_manager_dump(void) {pthread_mutex_lock(&fd_table_lock);printf(">> Opened FD List (thread-safe):\n");for (int i = 0; i < MAX_TRACKED_FD; i++) {if (fd_table[i].fd >= 0) {printf("  [fd=%d] tag=%s file=%s\n", fd_table[i].fd, fd_table[i].tag, fd_table[i].file);}}pthread_mutex_unlock(&fd_table_lock);
}void fd_manager_cleanup_all(void) {pthread_mutex_lock(&fd_table_lock);for (int i = 0; i < MAX_TRACKED_FD; i++) {if (fd_table[i].fd >= 0) {close(fd_table[i].fd);fd_table[i].fd = -1;fd_table[i].file[0] = '\0';fd_table[i].tag[0] = '\0';}}pthread_mutex_unlock(&fd_table_lock);
}

✅ 使用方式示例(多线程)

#include <pthread.h>
#include "fd_manager_threadsafe.h"void* thread_func(void* arg) {int fd = tracked_open("/dev/ttyS1", O_RDWR, "uart");if (fd >= 0) {// 模拟使用write(fd, "data", 4);tracked_close(fd);}return NULL;
}int main() {fd_manager_init();  // 初始化模块pthread_t t1, t2;pthread_create(&t1, NULL, thread_func, NULL);pthread_create(&t2, NULL, thread_func, NULL);pthread_join(t1, NULL);pthread_join(t2, NULL);fd_manager_dump();fd_manager_deinit();  // 清理资源return 0;
}

🧠 总结

特性说明
🔐 线程安全使用 pthread_mutex 对共享 fd 表加锁
📋 可追踪每个 fd 都记录来源、用途、路径
🧹 自动清理支持批量关闭所有打开的 fd
🧪 便于调试可随时打印当前所有活跃 fd 状态

Linux 文件描述符 (File Descriptor, FD)

一、文件描述符概念

在 Linux 中,文件描述符是操作系统为每个进程分配的整数,用于标识打开的文件或其他输入输出资源(如管道、套接字等)。文件描述符是 Linux 内核与用户空间交互的重要桥梁,是 I/O 操作的核心。

二、文件描述符的类型

文件描述符可以用于表示以下几种资源:

  1. 普通文件:例如文本文件、二进制文件。
  2. 设备文件:如 /dev/null 或终端设备 /dev/tty
  3. 管道:如命名管道或匿名管道。
  4. 套接字:网络通信的端点。
  5. 标准输入输出:默认分配的三个描述符:
    • 0:标准输入(stdin
    • 1:标准输出(stdout
    • 2:标准错误(stderr
三、文件描述符的分配
  • 当一个进程打开一个文件时,内核会分配一个最小可用的非负整数作为文件描述符。
  • 每个进程有自己独立的文件描述符表。
四、文件描述符的工作原理

文件描述符与文件系统的交互包括以下关键数据结构:

  1. 进程的文件描述符表
    • 每个进程都有一个文件描述符表(数组),其中的每个条目指向一个打开文件的记录。
  2. 系统打开文件表
    • 每个条目保存打开文件的状态,包括文件偏移量、访问模式等。
  3. 文件系统 inode 表
    • 包含文件的元数据,如权限、大小等。

工作流程

  • 当使用 open 打开文件时,内核分配一个文件描述符并关联到系统打开文件表。
  • 文件描述符指向打开文件表的一个条目,该条目再指向文件的具体 inode。
五、常用操作与开发示例
1. 打开文件

使用 open 打开文件,返回一个文件描述符。

#include <fcntl.h>
#include <unistd.h>
#include <stdio.h>int main() {int fd = open("example.txt", O_RDONLY);if (fd < 0) {perror("open");return 1;}printf("File descriptor: %d\n", fd);close(fd);return 0;
}
2. 读写文件

通过 readwrite 使用文件描述符进行 I/O 操作。

#include <fcntl.h>
#include <unistd.h>
#include <stdio.h>int main() {int fd = open("example.txt", O_RDWR | O_CREAT, 0644);if (fd < 0) {perror("open");return 1;}const char *content = "Hello, File Descriptor!";write(fd, content, 25);// Reset file offset and readlseek(fd, 0, SEEK_SET); char buffer[256];ssize_t nbytes = read(fd, buffer, sizeof(buffer) - 1);buffer[nbytes] = '\0';printf("Read content: %s\n", buffer);close(fd);return 0;
}
3. 复制文件描述符

使用 dupdup2 复制文件描述符。

#include <fcntl.h>
#include <unistd.h>
#include <stdio.h>int main() {int fd = open("example.txt", O_RDWR | O_CREAT, 0644);if (fd < 0) {perror("open");return 1;}int new_fd = dup(fd);write(new_fd, "Duplicated FD content\n", 23);close(fd);close(new_fd);return 0;
}
4. 关闭文件描述符

使用 close 释放文件描述符。

close(fd);
5. 设置非阻塞模式

通过 fcntl 修改文件描述符的标志。

#include <fcntl.h>
#include <unistd.h>int set_nonblocking(int fd) {int flags = fcntl(fd, F_GETFL, 0);if (flags == -1) return -1;return fcntl(fd, F_SETFL, flags | O_NONBLOCK);
}
六、开发中的常见用法
  1. 文件读写:通过 openreadwrite 操作文件。
  2. 进程通信:使用管道或套接字的文件描述符。
  3. 重定向 I/O:通过 dup2 实现标准输入输出重定向。
  4. 事件驱动开发:结合 selectepoll 使用文件描述符实现异步 I/O。
七、注意事项
  1. 资源泄漏:文件描述符需要及时关闭,否则可能耗尽。
  2. 错误检查:每次调用 openread 等函数后,检查返回值。
  3. 线程安全:多个线程共享文件描述符时需要同步。
  4. 最大限制:使用 ulimit -n 查看当前系统允许的最大文件描述符数量。
八、总结

文件描述符是 Linux I/O 的基础,开发者可以通过对其操作实现高效的资源管理、通信和文件操作。掌握文件描述符的用法和底层原理,可以为开发高性能 Linux 程序提供强大的工具。

在这里插入图片描述

相关文章:

Linux系统篇——文件描述符FD

&#x1f9e0; Linux 文件描述符&#xff08;File Descriptor&#xff09;详解与学习指南 一、什么是文件描述符&#xff08;fd&#xff09; 在 Linux 中&#xff0c;一切皆文件&#xff08;everything is a file&#xff09;&#xff0c;包括普通文件、目录、套接字&#xff…...

C++ Kafka客户端(cppkafka)安装与问题解决指南

一、cppkafka简介 cppkafka是一个现代C的Apache Kafka客户端库&#xff0c;它是对librdkafka的高级封装&#xff0c;旨在简化使用librdkafka的过程&#xff0c;同时保持最小的性能开销。 #mermaid-svg-qDUFSYLBf8cKkvdw {font-family:"trebuchet ms",verdana,arial,…...

MySQL的缓存策略

一、MySQL缓存方案用来解决什么 缓存用户定义的热点数据&#xff0c;用户直接从缓存获取热点数据&#xff0c;降低数据库的读写压力场景分析&#xff1a; 内存访问速度是磁盘访问速度 10 万倍&#xff08;数量级&#xff09;读的需求远远大于写的需求mysql 自身缓冲层跟业务无…...

ubuntu22.04卸载vscode

方法 1&#xff1a;通过 Snap 卸载 VSCode 如果你是通过 Snap 安装的 VSCode&#xff08;Ubuntu 22.04 默认推荐方式&#xff09;&#xff0c;按照以下步骤卸载&#xff1a; 检查是否通过 Snap 安装&#xff1a; bash snap list | grep code如果输出显示 code&#xff0c;说明…...

主流数据库排查与优化速查手册

主流数据库排查与优化速查手册&#xff08;优化版&#xff09; 一、连接失败 1.1 统一排查流程 #mermaid-svg-IIyarbd8VatJFN14 {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-IIyarbd8VatJFN14 .error-icon{fill:…...

MySQL 数据库优化:InnoDB 存储引擎深度解析:架构、调优与最佳实践

InnoDB 是 MySQL 的默认存储引擎,因其支持事务、行级锁和崩溃恢复等特性,广泛应用于高并发、数据一致性要求高的场景。本文将从 InnoDB 的核心架构、调优策略、监控诊断、高级特性 到 备份恢复 进行系统性分析,并结合代码示例与实战案例,帮助开发者全面掌握其应用与优化技巧…...

[AI算法] LLM训练-构建transformers custom model

文章目录 1. 继承与实现基础结构2. 支持 DeepSpeed 和 Accelerate 的注意事项a. 模型输出格式b. 设备管理c. 分布式训练兼容性d. DeepSpeed 特定优化 3. 训练脚本集成建议4. 测试与调试建议 在使用 Hugging Face 的 transformers 库时&#xff0c;若要自定义一个继承自 PreTrai…...

突发,苹果发布下一代 CarPlay Ultra

汽车的平均换代周期一般都超过5年&#xff0c;对于老旧燃油车而言&#xff0c;苹果的 Carplay 是黑暗中的明灯&#xff0c;是延续使用寿命的利器。 因为你可能不需要冰箱彩电大沙发&#xff0c;但一定需要大屏车载导航、倒车影像、车载听歌。如果原车不具备这个功能&#xff0…...

git克隆github项目到本地的三种方式

本文旨在使用git工具将别人发布在github上的项目保存到本地 1.安装git&#xff0c;创建github账户&#xff0c;并使用ssh关联自己的github账号和git&#xff0c;具体教程可以参照下面两篇文章&#xff1a; Github入门教程&#xff0c;适合新手学习&#xff08;非常详细&#…...

Excel MCP: 自动读取、提炼、分析Excel数据并生成可视化图表和分析报告

最近&#xff0c;一款Excel MCP Server的开源工具火了&#xff0c;看起来功能很强大&#xff0c;咱们今天来一探究竟。 基础环境 最近两年&#xff0c;大家都可以看到AI的发展有多快&#xff0c;我国超10亿参数的大模型&#xff0c;在短短一年之内&#xff0c;已经超过了100个&…...

香港 GPU 服务器优势及使用场景解析

在快速发展的科技领域&#xff0c;数据处理和复杂计算已成为众多行业的支柱&#xff0c;GPU 服务器的重要性不容小觑。GPU 服务器是内部集成一个或多个 GPU的物理服务器&#xff0c;用于执行每个用例所需的任务。而香港 GPU 服务器&#xff0c;是指部署在中国香港数据中心、配备…...

Go语言交替打印问题及多种实现方法

Go语言交替打印问题及多种实现方法 在并发编程中&#xff0c;多个线程&#xff08;或 goroutine&#xff09;交替执行任务是一个经典问题。本文将以 Go 语言为例&#xff0c;介绍如何实现多个 goroutine 交替打印数字的功能&#xff0c;并展示几种不同的实现方法。 Go 语言相关…...

Grafana分布统计:Heatmap面板

Heatmap是是Grafana v4.3版本以后新添加的可视化面板&#xff0c;通过热图可以直观的查看样本的分布情况。在Grafana v5.1版本中Heatmap完善了对Prometheus的支持。这部分&#xff0c;将介绍如何使用HeatmapPanel实现对Prometheus监控指标的可视化。 使用Heatmap可视化Histogr…...

rk3576 gstreamer opencv

安装gstreamer rk3588使用gstreamer推流_rk3588 gstreamer-CSDN博客 rk3588使用gstreamer推流_rk3588 gstreamer-CSDN博客 Installing on Linux sudo apt-get install libgstreamer1.0-dev libgstreamer-plugins-base1.0-dev libgstreamer-plugins-bad1.0-dev gstreamer1.0-pl…...

用户现场不支持路由映射,如何快速将安防监控EasyCVR视频汇聚平台映射到公网?

一、方案背景​ 随着数字化安防与智能交通管理发展&#xff0c;视频监控远程管理需求激增。EasyCVR作为专业视频融合平台&#xff0c;具备多协议接入等核心功能&#xff0c;是智能监控的重要工具。但实际部署中&#xff0c;当EasyCVR处于内网且路由器无法进行端口映射时&#…...

棋牌室台球室快速接入美团团购接口

北极星平台从2024年12月份开始慢慢关闭&#xff0c;现在很多开发者反馈北极星token已经不能刷新了&#xff0c;全部迁移到美团团购综合平台。 申请这个平台要求很高 1、保证金费用要15万起步 2、平台必须是二级等保和安全产品 &#xff0c;一个二级等保费用10万起步 所以很多…...

Qwen3技术报告解读:训练秘籍公开,推理与非推理模型统一,大模型蒸馏小模型(报告详细解读)

1.简介 Qwen3 是 Qwen 模型家族的最新版本&#xff0c;它是一系列大型语言模型&#xff08;LLMs&#xff09;&#xff0c;旨在提升性能、效率和多语言能力。基于广泛的训练&#xff0c;Qwen3 在推理、指令遵循、代理能力和多语言支持方面取得了突破性进展&#xff0c;具有以下…...

entity线段材质设置

在cesium中,我们可以改变其entity线段材质,这里以直线为例. 首先我们先创建一条直线 const redLine viewer.entities.add({polyline: {positions: Cesium.Cartesian3.fromDegreesArray([-75,35,-125,35,]),width: 5,material:material, 保存后可看到在地图上创建了一条线段…...

Word图片格式调整与转换工具

软件介绍 本文介绍的这款工具主要用于辅助Word文档处理。 图片排版功能 经常和Word打交道的人或许都有这样的困扰&#xff1a;插入的图片大小各异&#xff0c;排列也参差不齐。若不加以调整&#xff0c;遇到要求严格的领导&#xff0c;可能会让人颇为头疼。 而这款工具能够统…...

小刚说C语言刷题—1700请输出所有的2位数中,含有数字2的整数

1.题目描述 请输出所有的 2 位数中&#xff0c;含有数字 2 的整数有哪些&#xff0c;每行 1个&#xff0c;按照由小到大输出。 比如&#xff1a; 12、20、21、22、23… 都是含有数字 2的整数。 输入 无 输出 按题意要求由小到大输出符合条件的整数&#xff0c;每行 1 个。…...

视频抽帧并保存blob

视频抽帧 /*** description 获取文件中的每一帧* param { File } file* param { Number } time 每一帧的时间间隔(单位:秒)* param { Boolean } isUseInterval 是否使用间隔 为false只会获取这一帧* returns { Map }* example await captureFrame({ file, 20 }) > M…...

opencloudos 安装 mosquitto

更新系统并安装依赖 sudo dnf update -y sudo dnf install -y epel-release # 若需要 EPEL 额外仓库 sudo dnf install -y gcc-c cmake openssl-devel c-ares-devel libuuid-devel libwebsockets-devel安装 Mosquitto 通过默认仓库安装&#xff08;推荐&#xff09; sudo dn…...

STM32CubeMX使用SG90舵机角度0-180°

1. 配置步骤 1.1 硬件连接 舵机信号线 → STM32的PWM输出引脚&#xff08;如 PA2&#xff0c;对应定时器 TIM2_CH3&#xff09;。 电源和地 → 外接5V电源&#xff08;确保共地&#xff09;。 1.2 定时器配置&#xff08;以TIM2为例&#xff09; 在STM32CubeMX中&#xff1…...

【Umi】项目初始化配置和用户权限

app.tsx import { RunTimeLayoutConfig } from umijs/max; import { history, RequestConfig } from umi; import { getCurrentUser } from ./services/auth; import { message } from antd;// 获取用户信息 export async function getInitialState(): Promise<{currentUse…...

使用哈希表封装myunordered_set和myunordered_map

文章目录 使用哈希表封装myunordered_set和myunordered_map实现出复用哈希表框架&#xff0c;并支持insert支持迭代器的实现constKey不能被修改unordered_map支持[ ]结语 我们今天又见面啦&#xff0c;给生活加点impetus&#xff01;&#xff01;开启今天的编程之路&#xff01…...

光学变焦和数字变倍模块不同点概述!

一、光学变焦与数字变倍模块的不同点 1. 物理基础 光学变焦&#xff1a;通过调整镜头组中镜片的物理位置改变焦距&#xff0c;实现无损放大。例如&#xff0c;上海墨扬的MF-STAR吊舱采用30倍光学变焦镜头&#xff0c;焦距范围6~180mm&#xff0c;等效焦距可达997mm。 数字…...

Spring MVC 中请求处理流程及核心组件解析

在 Spring MVC 中&#xff0c;请求从客户端发送到服务器后&#xff0c;需要经过一系列组件的处理才能最终到达具体的 Controller 方法。这个过程涉及多个核心组件和复杂的映射机制&#xff0c;下面详细解析其工作流程&#xff1a; 1. 核心组件与请求流程 Spring MVC 的请求处…...

《100天精通Python——基础篇 2025 第19天:并发编程启蒙——理解CPU、线程与进程的那些事》

目录 一、计算机基础知识1.1 计算机发展简史1.2 计算机的分类1.2.1 超级计算机&#xff08;Supercomputer&#xff09;1.2.2 大型机&#xff08;Mainframe Computer&#xff09;1.2.3 迷你计算机&#xff08;Minicomputer&#xff09;---- 普通服务器1.2.4 工作站&#xff08;W…...

<PLC><视觉><机器人>基于海康威视视觉检测和UR机械臂,如何实现N点标定?

前言 本系列是关于PLC相关的博文,包括PLC编程、PLC与上位机通讯、PLC与下位驱动、仪器仪表等通讯、PLC指令解析等相关内容。 PLC品牌包括但不限于西门子、三菱等国外品牌,汇川、信捷等国内品牌。 除了PLC为主要内容外,相关设备如触摸屏(HMI)、交换机等工控产品,如果有…...

FC7300 WDG MCAL 配置引导

在WDG模块中,用户需要选择GPT资源,因此在配置WDG组件之前,需要先选择GPT通道。WDG包含三个组件,每一个组件对应不同的硬件。 Wdg:对应WDOG0Wdg_174_Instance1:对应WDOG1Wdg_174_Instance2:对应WDOG2一、WDG 组件 1. General Wdg Disable Allowed:是否允许在WDG运行过程…...

Leaflet 自定义瓦片地图与 PHP 大图切图算法 解决大图没办法在浏览器显示的问题

为什么使用leaflet 使用 Leaflet 来加载大图片&#xff08;尤其是通过瓦片化的方式&#xff09;是一种高效的解决方案&#xff0c;主要原因如下&#xff1a; 1. 性能优化 减少内存占用&#xff1a;直接加载大图片会占用大量内存&#xff0c;可能导致浏览器崩溃或性能下降。瓦片…...

MySQL——十、InnoDB引擎

MVCC 当前读&#xff1a; 读取的是记录的最新版本&#xff0c;读取时还要保证其他并发事务不能修改当前记录&#xff0c;会对读取的记录进行加锁。 -- 当前读 select ... lock in share mode(共享锁) select ... for update update insert delete (排他锁)快照读&#xff1a;…...

import pywinauto后tkinter.filedialog.askdirectory()无法调用,直接卡死,应如何解决

诸神缄默不语-个人技术博文与视频目录 具体情况就是我需要用pywinauto进行一些软件的自动化操作&#xff0c;同时需要将整个代码功能用tkinter的可视化界面来展示&#xff0c;在调用filedialog.askdirectory()的时候代码直接不运行了&#xff0c;加载不出来。我一开始还以为是…...

display:grid网格布局属性说明

网格父级 &#xff1a;display:grid&#xff08;块级网格&#xff09;/ inline-grid&#xff08;行内网格&#xff09; 注意&#xff1a;当设置网格布局&#xff0c;column、float、clear、vertical-align的属性是无效的。 HTML: <ul class"ls02 f18 mt50 sysmt30&…...

初识——QT

QT安装方法 一、项目创建流程 创建项目 入口&#xff1a;通过Qt Creator的欢迎页面或菜单栏&#xff08;文件→新建项目&#xff09;创建新项目。 项目类型&#xff1a;选择「Qt Widgets Application」。 路径要求&#xff1a;项目路径需为纯英文且不含特殊字符。 构建系统…...

力扣-78.子集

给你一个整数数组 nums &#xff0c;数组中的元素 互不相同 。返回该数组所有可能的子集&#xff08;幂集&#xff09;。 解集 不能 包含重复的子集。你可以按 任意顺序 返回解集。 class Solution {List<List<Integer>> res new ArrayList<>();List<I…...

python中字符串的操作

‌1. 字符串创建‌ 使用单引号、双引号或三引号创建字符串三引号适用于多行字符串&#xff0c;且可以自由包含单双引号原始字符串使用r前缀&#xff0c;如r’Hello\nWorld’会原样输出\n ‌2. 基本操作‌ 拼接&#xff1a;使用运算符或join()方法复制&#xff1a;使用*运算符…...

《Elasticsearch 源码解析与优化实战》笔记

术语 思维导图 基础和环境 1-2 主要流程 3-10 内部模块 11-17 优化和诊断 18-22 资料 https://elasticsearchbook.com/...

华为网路设备学习-22(路由器OSPF-LSA及特殊详解)

一、基本概念 OSPF协议的基本概念 OSPF是一种内部网关协议&#xff08;IGP&#xff09;&#xff0c;主要用于在自治系统&#xff08;AS&#xff09;内部使路由器获得远端网络的路由信息。OSPF是一种链路状态路由协议&#xff0c;不直接传递路由表&#xff0c;而是通过交换链路…...

多线程(四)

目录 一 . 单例模式 &#xff08;1&#xff09;什么是设计模式&#xff1f; &#xff08;2&#xff09;饿汉模式 &#xff08;3&#xff09;懒汉模式 二 . 指令重排序 今天咱们继续讲解多线程的相关内容 一 . 单例模式 &#xff08;1&#xff09;什么是设计模式&am…...

【设计模式】- 结构型模式

代理模式 给目标对象提供一个代理以控制对该对象的访问。外界如果需要访问目标对象&#xff0c;需要去访问代理对象。 分类&#xff1a; 静态代理&#xff1a;代理类在编译时期生成动态代理&#xff1a;代理类在java运行时生成 JDK代理CGLib代理 【主要角色】&#xff1a; 抽…...

python报错:使用json.dumps()时,报错type xxx is not json serializable错误原因及解决方案

文章目录 一、错误原因分析二、解决方案1. **自定义对象序列化方法一&#xff1a;使用default参数定义转换逻辑方法二&#xff1a;继承JSONEncoder类统一处理 2. **处理特殊数据类型场景一&#xff1a;datetime或numpy类型场景二&#xff1a;bytes类型 3. **处理复杂数据结构 三…...

Vue3中实现轮播图

目录 1. 轮播图介绍 2. 实现轮播图 2.1 准备工作 1、准备至少三张图片&#xff0c;并将图片文件名改为数字123 2、搭好HTML的标签 3、写好按钮和图片标签 ​编辑 2.2 单向绑定图片 2.3 在按钮里使用方法 2.4 运行代码 3. 完整代码 1. 轮播图介绍 首先&#xff0c;什么是…...

flutter缓存网络视频到本地,可离线观看

记录一下解决问题的过程&#xff0c;希望自己以后可以参考看看&#xff0c;解决更多的问题。 需求&#xff1a;flutter 缓存网络视频文件&#xff0c;可离线观看。 解决&#xff1a; 1&#xff0c;flutter APP视频播放组件调整&#xff1b; 2&#xff0c;找到视频播放组件&a…...

2025年Ai写PPT工具推荐,这5款Ai工具可以一键生成专业PPT

上个月给客户做产品宣讲时&#xff0c;我对着空白 PPT 页面熬到凌晨一点&#xff0c;光是调整文字排版就改了十几版&#xff0c;最后还是被吐槽 "内容零散没重点"。后来同事分享了几款 ai 写 PPT 工具&#xff0c;试完发现简直打开了新世界的大门 —— 不用手动写大纲…...

【深度学习】#11 优化算法

主要参考学习资料&#xff1a; 《动手学深度学习》阿斯顿张 等 著 【动手学深度学习 PyTorch版】哔哩哔哩跟李牧学AI 目录 深度学习中的优化挑战局部极小值鞍点梯度消失 凸性凸集凸函数 梯度下降一维梯度下降学习率局部极小值 多元梯度下降 随机梯度下降随机梯度更新动态学习率…...

数学复习笔记 13

前言 继续做线性相关的练习题&#xff0c;然后做矩阵的例题&#xff0c;还有矩阵的练习题。 646 A 明显是错的。因为假设系数全部是零&#xff0c;就不是线性相关了。要限制系数不全是零&#xff0c;才可以是线性相关。 B 这个说法好像没啥问题。系数全为零肯定线性组合的结…...

AI预测3D新模型百十个定位预测+胆码预测+去和尾2025年5月16日第79弹

从今天开始&#xff0c;咱们还是暂时基于旧的模型进行预测&#xff0c;好了&#xff0c;废话不多说&#xff0c;按照老办法&#xff0c;重点8-9码定位&#xff0c;配合三胆下1或下2&#xff0c;杀1-2个和尾&#xff0c;再杀6-8个和值&#xff0c;可以做到100-300注左右。 (1)定…...

阳台光伏+储能:安科瑞智能计量仪表来助力

随着可再生能源的普及和家庭储能需求的增长&#xff0c;阳台光伏储能系统逐渐成为家庭能源管理的新趋势。如何精准计量储能系统的发电量、用电量及电网交互数据&#xff0c;成为优化能源利用效率的关键。安科瑞计量仪表凭借高精度、多功能及智能化特性&#xff0c;为家庭阳台储…...

Unable to determine the device handle for GPU 0000:1A:00.0: Unknown Error

Unable to determine the device handle for GPU 0000:1A:00.0: Unknown Error 省流&#xff1a;我遇到这个问题重置bios设置就好了 这个错误信息表明系统无法识别或访问GPU&#xff08;0000:1A:00.0&#xff09;&#xff0c;通常与CUDA、驱动程序或硬件相关。以下是可能的原…...