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

linux定时器管理 timer_*系统调用及示例

linux定时器管理 timer_* 函数详解

1. 函数介绍

timer_ 函数系列*是Linux系统中用于定时器管理的一组函数,它们提供了精确的时间控制和定时功能。可以把timer_*函数想象成一个"精密时钟系统",允许你设置各种类型的定时器,包括一次性定时器、周期性定时器、以及高精度定时器。
这些函数基于POSIX定时器标准,提供了比传统alarm()函数更强大和灵活的功能。timer_*函数可以:

  • 创建和管理多个定时器
  • 设置一次性或周期性定时
  • 指定定时器到期时的行为(发送信号或执行回调)
  • 精确控制定时器的时间间隔
  • 查询和修改定时器状态

使用场景:

  • 网络服务器中的超时控制
  • 实时系统中的周期性任务
  • 游戏开发中的帧率控制
  • 系统监控和定时检查
  • 多媒体应用中的同步控制

2. 函数原型

#include <time.h>
#include <signal.h>// 创建定时器
int timer_create(clockid_t clockid, struct sigevent *sevp, timer_t *timerid);// 启动/修改定时器
int timer_settime(timer_t timerid, int flags,const struct itimerspec *new_value,struct itimerspec *old_value);// 获取定时器时间
int timer_gettime(timer_t timerid, struct itimerspec *curr_value);// 获取定时器超时次数
int timer_getoverrun(timer_t timerid);// 删除定时器
int timer_delete(timer_t timerid);

3. 功能

timer_*函数系列提供了完整的定时器管理功能:

  • timer_create: 创建一个新的定时器,指定时钟源和到期通知方式
  • timer_settime: 启动、停止或修改定时器的定时参数
  • timer_gettime: 查询定时器的当前状态和剩余时间
  • timer_getoverrun: 获取定时器的超限运行次数(当定时器到期但未被处理时)
  • timer_delete: 删除和清理定时器资源

4. 参数

timer_create参数:

  • clockid: 时钟类型

    • 类型:clockid_t
    • 含义:指定定时器使用的时钟源
    • 常用值:
      • CLOCK_REALTIME:系统实时时间
      • CLOCK_MONOTONIC:单调时钟(不会受系统时间调整影响)
      • CLOCK_PROCESS_CPUTIME_ID:进程CPU时间
      • CLOCK_THREAD_CPUTIME_ID:线程CPU时间
  • sevp: 信号事件结构

    • 类型:struct sigevent*
    • 含义:指定定时器到期时的通知方式
    • NULL表示使用默认的SIGALRM信号
  • timerid: 定时器ID

    • 类型:timer_t*
    • 含义:返回创建的定时器标识符

timer_settime参数:

  • timerid: 定时器ID

    • 类型:timer_t
    • 含义:要操作的定时器标识符
  • flags: 操作标志

    • 类型:int
    • 含义:控制定时器行为的标志
    • 常用值:
      • 0:相对时间
      • TIMER_ABSTIME:绝对时间
  • new_value: 新的定时器设置

    • 类型:const struct itimerspec*
    • 含义:指定定时器的新参数
  • old_value: 旧的定时器设置

    • 类型:struct itimerspec*
    • 含义:返回定时器之前的设置(可为NULL)

5. 返回值

  • 成功: 返回0
  • 失败: 返回-1,并设置errno错误码
    • EINVAL:参数无效
    • ENOMEM:内存不足
    • EPERM:权限不足
    • EAGAIN:资源暂时不可用

6. 相似函数或关联函数

  • alarm(): 传统的一次性定时器函数
  • setitimer(): 更灵活的间隔定时器函数
  • sleep()/usleep(): 简单的延迟函数
  • clock_gettime(): 获取时钟时间
  • nanosleep(): 高精度睡眠函数
  • signal()/sigaction(): 信号处理函数

7. 示例代码

示例1:基础timer使用 - 简单定时器

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <time.h>
#include <signal.h>
#include <string.h>
#include <errno.h>// 定时器信号处理函数
void timer_handler(int sig, siginfo_t *si, void *uc) {timer_t *tidp = si->si_value.sival_ptr;printf("[%ld] 定时器到期! 定时器ID: %p\n", time(NULL), (void*)*tidp);
}int main() {timer_t timerid;struct sigevent sev;struct itimerspec its;struct sigaction sa;printf("=== 基础定时器示例 ===\n");printf("当前时间: %ld\n", time(NULL));// 设置信号处理函数sa.sa_flags = SA_SIGINFO;sa.sa_sigaction = timer_handler;sigemptyset(&sa.sa_mask);if (sigaction(SIGRTMIN, &sa, NULL) == -1) {perror("sigaction");exit(EXIT_FAILURE);}// 创建定时器sev.sigev_notify = SIGEV_SIGNAL;sev.sigev_signo = SIGRTMIN;sev.sigev_value.sival_ptr = &timerid;if (timer_create(CLOCK_REALTIME, &sev, &timerid) == -1) {perror("timer_create");exit(EXIT_FAILURE);}printf("定时器创建成功,ID: %p\n", (void*)timerid);// 设置定时器:5秒后开始,每2秒触发一次its.it_value.tv_sec = 5;     // 初始延迟5秒its.it_value.tv_nsec = 0;its.it_interval.tv_sec = 2;  // 周期间隔2秒its.it_interval.tv_nsec = 0;if (timer_settime(timerid, 0, &its, NULL) == -1) {perror("timer_settime");exit(EXIT_FAILURE);}printf("定时器已启动:5秒后首次触发,之后每2秒触发一次\n");printf("程序将运行20秒...\n\n");// 等待定时器触发sleep(20);// 停止定时器its.it_value.tv_sec = 0;its.it_value.tv_nsec = 0;its.it_interval.tv_sec = 0;its.it_interval.tv_nsec = 0;if (timer_settime(timerid, 0, &its, NULL) == -1) {perror("timer_settime");exit(EXIT_FAILURE);}printf("\n定时器已停止\n");// 删除定时器if (timer_delete(timerid) == -1) {perror("timer_delete");exit(EXIT_FAILURE);}printf("定时器已删除\n");return 0;
}

示例2:多种定时器类型和时钟源

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <time.h>
#include <signal.h>
#include <string.h>#define NUM_TIMERS 4timer_t timers[NUM_TIMERS];
int timer_counts[NUM_TIMERS] = {0};// 定时器信号处理函数
void timer_handler(int sig, siginfo_t *si, void *uc) {int timer_index = si->si_value.sival_int;timer_counts[timer_index]++;printf("[%ld] 定时器 %d 到期第 %d 次\n", time(NULL), timer_index, timer_counts[timer_index]);// 演示timer_gettimestruct itimerspec curr_value;if (timer_gettime(timers[timer_index], &curr_value) == 0) {printf("  剩余时间: %ld.%09ld 秒\n", curr_value.it_value.tv_sec, curr_value.it_value.tv_nsec);}// 演示timer_getoverrunint overrun = timer_getoverrun(timers[timer_index]);if (overrun > 0) {printf("  超限运行: %d 次\n", overrun);}
}int main() {struct sigaction sa;struct sigevent sev;struct itimerspec its;int i;printf("=== 多种定时器类型示例 ===\n");printf("当前时间: %ld\n\n", time(NULL));// 设置信号处理函数sa.sa_flags = SA_SIGINFO;sa.sa_sigaction = timer_handler;sigemptyset(&sa.sa_mask);if (sigaction(SIGRTMIN, &sa, NULL) == -1) {perror("sigaction");exit(EXIT_FAILURE);}// 创建不同类型的定时器for (i = 0; i < NUM_TIMERS; i++) {// 设置信号事件sev.sigev_notify = SIGEV_SIGNAL;sev.sigev_signo = SIGRTMIN;sev.sigev_value.sival_int = i;clockid_t clock_type;const char* clock_name;switch(i) {case 0:clock_type = CLOCK_REALTIME;clock_name = "CLOCK_REALTIME";break;case 1:clock_type = CLOCK_MONOTONIC;clock_name = "CLOCK_MONOTONIC";break;case 2:clock_type = CLOCK_PROCESS_CPUTIME_ID;clock_name = "CLOCK_PROCESS_CPUTIME_ID";break;case 3:clock_type = CLOCK_THREAD_CPUTIME_ID;clock_name = "CLOCK_THREAD_CPUTIME_ID";break;default:clock_type = CLOCK_REALTIME;clock_name = "DEFAULT";break;}// 创建定时器if (timer_create(clock_type, &sev, &timers[i]) == -1) {printf("创建定时器 %d (%s) 失败: %s\n", i, clock_name, strerror(errno));continue;}printf("定时器 %d (%s) 创建成功\n", i, clock_name);// 设置不同的定时参数switch(i) {case 0: // 一次性定时器its.it_value.tv_sec = 3 + i;     // 3秒后触发its.it_value.tv_nsec = 0;its.it_interval.tv_sec = 0;      // 不重复its.it_interval.tv_nsec = 0;printf("  设置为一次性定时器,%d秒后触发\n", 3 + i);break;case 1: // 短周期定时器its.it_value.tv_sec = 2;         // 2秒后首次触发its.it_value.tv_nsec = 0;its.it_interval.tv_sec = 1;      // 每1秒重复its.it_interval.tv_nsec = 0;printf("  设置为周期性定时器,2秒后开始,每1秒触发\n");break;case 2: // 长周期定时器its.it_value.tv_sec = 5;         // 5秒后首次触发its.it_value.tv_nsec = 500000000; // 500毫秒its.it_interval.tv_sec = 3;      // 每3秒重复its.it_interval.tv_nsec = 0;printf("  设置为周期性定时器,5.5秒后开始,每3秒触发\n");break;case 3: // 快速定时器its.it_value.tv_sec = 1;         // 1秒后首次触发its.it_value.tv_nsec = 0;its.it_interval.tv_sec = 0;      // 每0.5秒重复its.it_interval.tv_nsec = 500000000; // 500毫秒printf("  设置为周期性定时器,1秒后开始,每0.5秒触发\n");break;}// 启动定时器if (timer_settime(timers[i], 0, &its, NULL) == -1) {perror("timer_settime");exit(EXIT_FAILURE);}}printf("\n所有定时器已启动,程序运行20秒...\n\n");// 运行一段时间观察定时器效果sleep(20);// 停止所有定时器printf("\n=== 停止所有定时器 ===\n");its.it_value.tv_sec = 0;its.it_value.tv_nsec = 0;its.it_interval.tv_sec = 0;its.it_interval.tv_nsec = 0;for (i = 0; i < NUM_TIMERS; i++) {if (timer_settime(timers[i], 0, &its, NULL) == -1) {printf("停止定时器 %d 失败\n", i);} else {printf("定时器 %d 已停止\n", i);}}// 删除所有定时器printf("\n=== 删除所有定时器 ===\n");for (i = 0; i < NUM_TIMERS; i++) {if (timer_delete(timers[i]) == -1) {printf("删除定时器 %d 失败\n", i);} else {printf("定时器 %d 已删除\n", i);}}// 显示统计信息printf("\n=== 定时器触发统计 ===\n");for (i = 0; i < NUM_TIMERS; i++) {printf("定时器 %d 触发次数: %d\n", i, timer_counts[i]);}return 0;
}

示例3:高精度定时器和绝对时间定时

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <time.h>
#include <signal.h>
#include <string.h>timer_t timerid;
int trigger_count = 0;// 定时器信号处理函数
void timer_handler(int sig, siginfo_t *si, void *uc) {trigger_count++;struct timespec current_time;clock_gettime(CLOCK_REALTIME, &current_time);printf("[%ld.%09ld] 定时器第 %d 次触发\n", current_time.tv_sec, current_time.tv_nsec, trigger_count);
}// 获取当前时间字符串
void print_current_time() {struct timespec ts;clock_gettime(CLOCK_REALTIME, &ts);printf("当前时间: %ld.%09ld\n", ts.tv_sec, ts.tv_nsec);
}int main() {struct sigaction sa;struct sigevent sev;struct itimerspec its;struct timespec current_time;printf("=== 高精度定时器和绝对时间示例 ===\n");print_current_time();printf("\n");// 设置信号处理函数sa.sa_flags = SA_SIGINFO;sa.sa_sigaction = timer_handler;sigemptyset(&sa.sa_mask);if (sigaction(SIGRTMIN, &sa, NULL) == -1) {perror("sigaction");exit(EXIT_FAILURE);}// 创建定时器sev.sigev_notify = SIGEV_SIGNAL;sev.sigev_signo = SIGRTMIN;sev.sigev_value.sival_ptr = &timerid;if (timer_create(CLOCK_REALTIME, &sev, &timerid) == -1) {perror("timer_create");exit(EXIT_FAILURE);}printf("高精度定时器创建成功\n");// 示例1: 相对时间定时器(高精度)printf("\n--- 相对时间定时器 ---\n");print_current_time();// 设置1.5秒的延迟定时器its.it_value.tv_sec = 1;its.it_value.tv_nsec = 500000000;  // 500毫秒its.it_interval.tv_sec = 0;its.it_interval.tv_nsec = 0;if (timer_settime(timerid, 0, &its, NULL) == -1) {perror("timer_settime");exit(EXIT_FAILURE);}printf("设置1.5秒延迟定时器...\n");sleep(3);  // 等待定时器触发// 示例2: 周期性高精度定时器printf("\n--- 周期性高精度定时器 ---\n");print_current_time();// 设置周期性定时器:0.1秒后开始,每0.2秒触发its.it_value.tv_sec = 0;its.it_value.tv_nsec = 100000000;   // 100毫秒its.it_interval.tv_sec = 0;its.it_interval.tv_nsec = 200000000; // 200毫秒if (timer_settime(timerid, 0, &its, NULL) == -1) {perror("timer_settime");exit(EXIT_FAILURE);}printf("设置周期性定时器:100毫秒后开始,每200毫秒触发\n");printf("运行5秒观察效果...\n\n");sleep(5);// 停止定时器its.it_value.tv_sec = 0;its.it_value.tv_nsec = 0;its.it_interval.tv_sec = 0;its.it_interval.tv_nsec = 0;if (timer_settime(timerid, 0, &its, NULL) == -1) {perror("timer_settime");exit(EXIT_FAILURE);}printf("\n周期性定时器已停止\n");printf("触发次数: %d\n", trigger_count);// 示例3: 绝对时间定时器printf("\n--- 绝对时间定时器 ---\n");trigger_count = 0;// 获取当前时间并设置5秒后的绝对时间if (clock_gettime(CLOCK_REALTIME, &current_time) == -1) {perror("clock_gettime");exit(EXIT_FAILURE);}print_current_time();// 设置绝对时间:当前时间+3秒struct itimerspec abs_its;abs_its.it_value.tv_sec = current_time.tv_sec + 3;abs_its.it_value.tv_nsec = current_time.tv_nsec;abs_its.it_interval.tv_sec = 0;abs_its.it_interval.tv_nsec = 0;printf("设置绝对时间定时器:3秒后触发\n");if (timer_settime(timerid, TIMER_ABSTIME, &abs_its, NULL) == -1) {perror("timer_settime (绝对时间)");exit(EXIT_FAILURE);}sleep(5);  // 等待定时器触发// 示例4: 定时器状态查询printf("\n--- 定时器状态查询 ---\n");// 重新设置一个周期性定时器用于测试its.it_value.tv_sec = 1;its.it_value.tv_nsec = 0;its.it_interval.tv_sec = 2;its.it_interval.tv_nsec = 0;if (timer_settime(timerid, 0, &its, NULL) == -1) {perror("timer_settime");exit(EXIT_FAILURE);}printf("设置新的周期性定时器:1秒后开始,每2秒触发\n");// 查询定时器状态sleep(1);  // 等待首次触发后struct itimerspec query_its;if (timer_gettime(timerid, &query_its) == 0) {printf("定时器状态查询结果:\n");printf("  到期间隔: %ld.%09ld 秒\n", query_its.it_interval.tv_sec, query_its.it_interval.tv_nsec);printf("  剩余时间: %ld.%09ld 秒\n", query_its.it_value.tv_sec, query_its.it_value.tv_nsec);}// 演示timer_getoverrunprintf("定时器超限运行测试(快速触发):\n");sleep(6);int overrun = timer_getoverrun(timerid);printf("超限运行次数: %d\n", overrun);// 清理its.it_value.tv_sec = 0;its.it_value.tv_nsec = 0;its.it_interval.tv_sec = 0;its.it_interval.tv_nsec = 0;timer_settime(timerid, 0, &its, NULL);timer_delete(timerid);printf("\n所有测试完成\n");return 0;
}

示例4:定时器在实际应用中的使用

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <time.h>
#include <signal.h>
#include <string.h>
#include <pthread.h>#define MAX_TASKS 10
#define HEARTBEAT_INTERVAL 5// 任务结构体
typedef struct {int id;char name[50];int interval_seconds;time_t last_run;int run_count;
} task_t;task_t tasks[MAX_TASKS];
int task_count = 0;
timer_t heartbeat_timer;
timer_t task_timers[MAX_TASKS];
pthread_mutex_t task_mutex = PTHREAD_MUTEX_INITIALIZER;// 添加任务
int add_task(int id, const char* name, int interval) {if (task_count >= MAX_TASKS) {return -1;}tasks[task_count].id = id;strncpy(tasks[task_count].name, name, sizeof(tasks[task_count].name) - 1);tasks[task_count].interval_seconds = interval;tasks[task_count].last_run = 0;tasks[task_count].run_count = 0;return task_count++;
}// 任务执行函数
void execute_task(int task_index) {pthread_mutex_lock(&task_mutex);time_t current_time = time(NULL);tasks[task_index].last_run = current_time;tasks[task_index].run_count++;printf("[%ld] 执行任务 %d (%s): 第 %d 次执行\n", current_time, tasks[task_index].id, tasks[task_index].name, tasks[task_index].run_count);pthread_mutex_unlock(&task_mutex);
}// 任务定时器处理函数
void task_timer_handler(int sig, siginfo_t *si, void *uc) {int task_index = si->si_value.sival_int;execute_task(task_index);
}// 心跳定时器处理函数
void heartbeat_handler(int sig, siginfo_t *si, void *uc) {static int heartbeat_count = 0;heartbeat_count++;printf("[%ld] 系统心跳 #%d\n", time(NULL), heartbeat_count);// 显示所有任务状态pthread_mutex_lock(&task_mutex);printf("  任务状态:\n");for (int i = 0; i < task_count; i++) {printf("    %s: 执行%d次, 最后执行: %s", tasks[i].name, tasks[i].run_count,tasks[i].last_run ? ctime(&tasks[i].last_run) : "从未执行\n");if (tasks[i].last_run) {// 移除ctime返回的换行符char* newline = strchr(ctime(&tasks[i].last_run), '\n');if (newline) *newline = '\0';printf("%s\n", ctime(&tasks[i].last_run));}}pthread_mutex_unlock(&task_mutex);
}// 初始化定时器系统
int init_timer_system() {struct sigaction sa;// 设置任务定时器信号处理sa.sa_flags = SA_SIGINFO;sa.sa_sigaction = task_timer_handler;sigemptyset(&sa.sa_mask);if (sigaction(SIGRTMIN, &sa, NULL) == -1) {perror("sigaction task");return -1;}// 设置心跳定时器信号处理sa.sa_sigaction = heartbeat_handler;if (sigaction(SIGRTMIN + 1, &sa, NULL) == -1) {perror("sigaction heartbeat");return -1;}return 0;
}// 启动任务定时器
int start_task_timer(int task_index) {struct sigevent sev;struct itimerspec its;// 创建定时器sev.sigev_notify = SIGEV_SIGNAL;sev.sigev_signo = SIGRTMIN;sev.sigev_value.sival_int = task_index;if (timer_create(CLOCK_REALTIME, &sev, &task_timers[task_index]) == -1) {perror("timer_create task");return -1;}// 设置定时器its.it_value.tv_sec = tasks[task_index].interval_seconds;its.it_value.tv_nsec = 0;its.it_interval.tv_sec = tasks[task_index].interval_seconds;its.it_interval.tv_nsec = 0;if (timer_settime(task_timers[task_index], 0, &its, NULL) == -1) {perror("timer_settime task");return -1;}printf("任务定时器 %s 已启动,间隔 %d 秒\n", tasks[task_index].name, tasks[task_index].interval_seconds);return 0;
}// 启动心跳定时器
int start_heartbeat_timer() {struct sigevent sev;struct itimerspec its;// 创建心跳定时器sev.sigev_notify = SIGEV_SIGNAL;sev.sigev_signo = SIGRTMIN + 1;sev.sigev_value.sival_int = 0;if (timer_create(CLOCK_REALTIME, &sev, &heartbeat_timer) == -1) {perror("timer_create heartbeat");return -1;}// 设置心跳定时器(每5秒触发一次)its.it_value.tv_sec = HEARTBEAT_INTERVAL;its.it_value.tv_nsec = 0;its.it_interval.tv_sec = HEARTBEAT_INTERVAL;its.it_interval.tv_nsec = 0;if (timer_settime(heartbeat_timer, 0, &its, NULL) == -1) {perror("timer_settime heartbeat");return -1;}printf("心跳定时器已启动,间隔 %d 秒\n", HEARTBEAT_INTERVAL);return 0;
}int main() {printf("=== 实际应用中的定时器系统 ===\n");printf("启动时间: %s", ctime(&(time_t){time(NULL)}));// 初始化定时器系统if (init_timer_system() == -1) {fprintf(stderr, "初始化定时器系统失败\n");exit(EXIT_FAILURE);}// 添加一些测试任务add_task(1, "数据备份", 10);add_task(2, "日志清理", 15);add_task(3, "状态检查", 5);add_task(4, "性能监控", 3);printf("已添加 %d 个任务\n", task_count);// 启动所有任务定时器for (int i = 0; i < task_count; i++) {if (start_task_timer(i) == -1) {fprintf(stderr, "启动任务定时器 %d 失败\n", i);}}// 启动心跳定时器if (start_heartbeat_timer() == -1) {fprintf(stderr, "启动心跳定时器失败\n");}printf("\n定时器系统运行中...\n");printf("程序将运行60秒,按Ctrl+C退出\n\n");// 运行主循环for (int i = 0; i < 60; i++) {sleep(1);// 每10秒显示一次统计信息if ((i + 1) % 10 == 0) {printf("[%ld] === 运行统计 ===\n", time(NULL));pthread_mutex_lock(&task_mutex);for (int j = 0; j < task_count; j++) {printf("  %s: 执行 %d 次\n", tasks[j].name, tasks[j].run_count);}pthread_mutex_unlock(&task_mutex);printf("==================\n\n");}}// 清理定时器printf("清理定时器...\n");// 停止并删除心跳定时器struct itimerspec stop_its = {{0, 0}, {0, 0}};timer_settime(heartbeat_timer, 0, &stop_its, NULL);timer_delete(heartbeat_timer);// 停止并删除所有任务定时器for (int i = 0; i < task_count; i++) {timer_settime(task_timers[i], 0, &stop_its, NULL);timer_delete(task_timers[i]);}printf("定时器系统已停止\n");// 显示最终统计printf("\n=== 最终统计 ===\n");pthread_mutex_lock(&task_mutex);for (int i = 0; i < task_count; i++) {printf("%s: 执行 %d 次\n", tasks[i].name, tasks[i].run_count);}pthread_mutex_unlock(&task_mutex);return 0;
}

编译和运行

# 编译示例1
gcc -o timer_example1 timer_example1.c -lrt
./timer_example1# 编译示例2
gcc -o timer_example2 timer_example2.c -lrt
./timer_example2# 编译示例3
gcc -o timer_example3 timer_example3.c -lrt
./timer_example3# 编译示例4
gcc -o timer_example4 timer_example4.c -lrt -lpthread
./timer_example4

重要注意事项

1. 链接库: 使用timer_*函数需要链接实时库(-lrt)
2. 信号处理: 定时器通常通过信号通知,需要注意信号安全
3. 精度限制: 实际精度受系统调度和负载影响
4. 资源管理: 必须正确删除定时器以避免资源泄漏
5. 线程安全: 在多线程环境中使用时需要适当的同步
6. 错误处理: 所有timer_*函数都可能失败,必须检查返回值
7. 时钟选择: 不同时钟源适用于不同的应用场景

通过这些示例,你可以理解timer_*函数在定时控制方面的强大功能,它们为Linux应用程序提供了精确、灵活的时间管理能力。

http://www.dtcms.com/a/317005.html

相关文章:

  • LeetCode 112. 路径总和解题思路详解(BFS算法深入理解)
  • AI模型整合包上线!一键部署ComfyUI,2.19TB模型全解析
  • ES(Elasticsearch)进程掉线(节点脱离集群)问题
  • 协同过滤基础——基线预测器(Baseline Predictors)
  • 深入理解 Ext 系列文件系统:从磁盘物理到文件系统原理
  • QtPromise第三方库的介绍和使用
  • STM32学习笔记2-GPIO的输出模式
  • 宠智灵宠物AI大模型聚焦医疗核心场景,提升临床决策能力
  • Bilateral Reference for High-Resolution Dichotomous Image Segmentation
  • mmsegmentation·数据结构
  • 《零基础入门AI:传统机器学习进阶(从拟合概念到K-Means算法)》
  • 力扣刷题日常(15-16)
  • 深信服GO面试题及参考答案(下)
  • MCP与Function Calling
  • 三极管基本放大电路静态及动态参数计算
  • 【C++】类和对象2
  • nfs(网络文件系统)+autofs(自动挂载服务)
  • 创维智能融合终端DT741_移动版_S905L3芯片_安卓9_线刷固件包
  • I6328A 蓝牙模块 做 串口透传 操作记录
  • pipeline方法关系抽取--课堂笔记
  • 海信IP810N/海信IP811N_海思MV320-安卓9.0主板-TTL烧录包-可救砖
  • 检索召回率优化探究四:基于LangChain0.3集成Milvu2.5向量数据库构建的智能问答系统
  • 【基础】第八篇 Java 位运算符详解:从基础到实战应用
  • 数据结构:双向链表、循环链表、内核链表
  • 【文本左右对齐】
  • 落霞归雁:从自然之道到“存内计算”——用算法思维在芯片里开一条“数据高速航道”
  • SpringCloud学习-------Feign详解
  • 面试题:前端权限设计
  • 【Spring Cloud】-- 注册中心
  • 广东省省考备考(第六十七天8.5)——资料分析、数量(强化训练)