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 4

timer_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_gettime
    struct 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_getoverrun
    int 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_getoverrun
    printf("定时器超限运行测试(快速触发):\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应用程序提供了精确、灵活的时间管理能力。

此条目发表在未分类分类目录。将固定链接加入收藏夹。

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注