UNIX下C语言编程与实践39-UNIX 定时器:alarm 函数与 setitimer 函数的使用与对比

从秒级普通定时到毫秒级精确定时,掌握 UNIX 系统定时机制的核心工具

一、UNIX 定时器的核心定位与分类

在 UNIX 系统中,定时器(Timer) 是实现"定时触发事件"的核心机制,其本质是"内核在指定时间后向进程发送特定信号",进程通过捕获信号执行预设逻辑(如定时任务、超时处理)。根据精度和功能差异,UNIX 定时器主要分为两类:

  • 普通定时器(alarm 函数):秒级精度,仅支持"一次定时"或"覆盖式定时",功能简单,适用于对精度要求不高的场景(如超时提醒、简单定时任务);
  • 精确定时器(setitimer 函数):理论毫秒级精度,支持三种计时类型(真实时间、用户态时间、用户态+核心态时间)和"重复定时",功能灵活,适用于高精度、复杂定时场景(如性能监控、高频任务调度)。

两种定时器均依赖"信号触发"机制(如 SIGALRMSIGVTALRM),进程需通过信号捕获函数响应定时事件,本质是"异步定时"------定时器触发不阻塞进程主流程,而是通过信号中断实现。

二、普通定时器:alarm 函数的使用

alarm 函数是 UNIX 系统中最基础的定时接口,定义在 <unistd.h> 头文件中,核心功能是"在指定秒数后向进程发送 SIGALRM 信号",仅支持秒级精度和简单定时逻辑。

1. 函数原型与核心参数

c 复制代码
#include <unistd.h>

// 功能:设置秒级定时器,指定秒数后发送 SIGALRM 信号
// 参数:
//   seconds:定时秒数,取值 >= 0;
//     - 若 seconds > 0:设置新定时器,seconds 秒后触发;
//     - 若 seconds = 0:取消当前已设置的 alarm 定时器。
// 返回值:
//   - 成功:返回之前未到期的定时器剩余秒数(若无可返回 0);
//   - 失败:返回 -1(极少发生,通常因参数无效)。
unsigned int alarm(unsigned int seconds);

关键特性

  • 覆盖性 :若进程已设置未到期的 alarm 定时器,再次调用 alarm(seconds) 会覆盖原定时器,返回原定时器的剩余秒数;
  • 一次性 :定时器触发(发送 SIGALRM)后自动失效,若需重复定时,需在信号捕获函数中重新调用 alarm
  • 信号依赖 :定时器触发的核心是 SIGALRM 信号,若进程忽略或未捕获该信号,默认行为是终止进程(需特别注意)。

2. 实战:alarm 函数的典型用法

实例 1:基础定时------3 秒后触发 SIGALRM 信号

以下为规范格式后的代码和说明:

代码部分

c 复制代码
#include <stdio.h>
#include <unistd.h>
#include <signal.h>
#include <stdlib.h>

// SIGALRM 信号捕获函数
void sigalrm_handler(int sig) {
    printf("捕获到 SIGALRM 信号(定时时间到),程序退出\n");
    exit(EXIT_SUCCESS);
}

int main() {
    // 1. 捕获 SIGALRM 信号(避免默认终止)
    if (signal(SIGALRM, sigalrm_handler) == SIG_ERR) {
        perror("signal 注册 SIGALRM 失败");
        return 1;
    }

    // 2. 设置 3 秒后触发定时器
    unsigned int remaining = alarm(3);
    printf("已设置 3 秒定时器,之前无未到期定时器,返回值:%u\n", remaining);

    // 3. 主进程阻塞等待(避免提前退出)
    printf("主进程等待定时器触发...\n");
    while (1) {
        sleep(1);
        printf("等待中...\n");
    }
    return 0;
}

编译与运行

bash 复制代码
# 1. 编译程序
gcc alarm_basic.c -o alarm_basic

# 2. 运行程序
./alarm_basic

预期输出

复制代码
已设置 3 秒定时器,之前无未到期定时器,返回值:0
主进程等待定时器触发...
等待中...
等待中...
等待中...
捕获到 SIGALRM 信号(定时时间到),程序退出
实例 2:重复定时------每隔 1 秒触发一次 SIGALRM
c 复制代码
#include <stdio.h>
#include <unistd.h>
#include <signal.h>
#include <stdlib.h>

// 全局计数:记录定时触发次数(volatile 避免编译器优化)
volatile int count = 0;

// SIGALRM 捕获函数:重新设置定时器实现重复定时
void sigalrm_handler(int sig) {
    count++;
    printf("第 %d 次定时触发(每隔 1 秒)\n", count);

    // 触发 5 次后退出
    if (count >= 5) {
        printf("已触发 5 次,程序退出\n");
        exit(EXIT_SUCCESS);
    }

    // 重新设置 1 秒定时器,实现重复触发
    alarm(1);
}

int main() {
    // 注册 SIGALRM 捕获函数
    if (signal(SIGALRM, sigalrm_handler) == SIG_ERR) {
        perror("signal 注册失败");
        return 1;
    }

    // 首次设置 1 秒定时器
    alarm(1);
    printf("重复定时器已启动,每隔 1 秒触发一次(共 5 次)\n");

    // 主进程循环等待
    while (1) {
        pause(); // 阻塞等待信号,比 sleep 更高效
    }
    return 0;
}

编译与运行

bash 复制代码
gcc alarm_repeat.c -o alarm_repeat
./alarm_repeat

预期输出

复制代码
重复定时器已启动,每隔 1 秒触发一次(共 5 次)
第 1 次定时触发(每隔 1 秒)
第 2 次定时触发(每隔 1 秒)
第 3 次定时触发(每隔 1 秒)
第 4 次定时触发(每隔 1 秒)
第 5 次定时触发(每隔 1 秒)
已触发 5 次,程序退出

关键技巧 :使用 pause() 替代 sleep(1) 等待信号,pause() 会一直阻塞直到收到任意信号,避免 sleep 的时间误差,更适合信号驱动的场景。

三、精确定时器:setitimer 函数的使用

setitimer 函数是 UNIX 系统提供的增强型定时接口,定义在 <sys/time.h> 头文件中。相比 alarm 函数,它支持毫秒级精度、三种计时类型和自动重复定时,功能更强大,适用于高精度定时场景。

1. 函数原型与核心参数

c 复制代码
#include <sys/time.h>

// 功能:设置精确定时器,支持三种类型和重复定时
// 参数:
//   which:定时器类型(ITIMER_REAL / ITIMER_VIRT / ITIMER_PROF);
//   new_value:新定时器参数(定时时间、重复间隔);
//   old_value:非 NULL 时,存储之前定时器的参数(用于恢复);
// 返回值:成功返回 0,失败返回 -1,错误码存入 errno。
int setitimer(int which, const struct itimerval *new_value, struct itimerval *old_value);

// 定时器参数结构体:包含"初始定时时间"和"重复间隔时间"
struct itimerval {
    struct timeval it_interval; // 重复定时的间隔时间(0 表示仅一次)
    struct timeval it_value;    // 首次定时的时间(0 表示取消定时器)
};

// 时间结构体:支持秒和微秒(理论精度 1 微秒,实际受系统调度影响)
struct timeval {
    time_t      tv_sec;      // 秒数
    suseconds_t tv_usec;     // 微秒数(0 ~ 999999)
};

核心概念解析

  • struct itimerval 的作用:
    • it_value:首次触发定时器的时间(如 {1, 500000} 表示 1.5 秒后首次触发);
    • it_interval:首次触发后,重复定时的间隔时间(如 {1, 500000} 表示每隔 1.5 秒重复触发;为 {0, 0} 表示仅触发一次)。
  • 取消定时器 :将 new_value->it_value 设置为 {0, 0},调用 setitimer 即可取消对应类型的定时器。

2. setitimer 的三种定时器类型

setitimer 支持三种不同的计时类型,对应不同的时间统计范围和触发信号,适用于不同场景:

定时器类型 计时范围 触发信号 核心用途 精度影响因素
ITIMER_REAL 真实时间(墙钟时间),无论进程是否运行,时间都会累积 SIGALRM 通用定时场景(如超时提醒、定时任务调度),与 alarm 函数功能重叠 系统负载(高负载时,信号可能延迟送达),理论精度 1 微秒,实际约 10~100 微秒
ITIMER_VIRT 进程在用户态运行的时间(仅统计进程执行用户代码的时间,内核态时间不累积) SIGVTALRM 用户态代码性能监控(如统计函数执行耗时、限制用户态运行时间) 进程调度(仅进程在用户态时计时),精度较高,不受其他进程影响
ITIMER_PROF 进程在用户态 + 核心态运行的总时间(统计进程占用 CPU 的所有时间) SIGPROF 进程总 CPU 占用监控(如性能分析、限制进程总 CPU 时间) CPU 调度(仅进程占用 CPU 时计时),精度与 ITIMER_VIRT 相当

3. 实战:setitimer 函数的典型用法

实例 1:ITIMER_REAL 类型------1.5 秒重复定时(真实时间)
c 复制代码
#include <stdio.h>
#include <sys/time.h>
#include <signal.h>
#include <stdlib.h>

volatile int count = 0;

// SIGALRM 捕获函数(ITIMER_REAL 触发)
void sigalrm_handler(int sig) {
    count++;
    printf("第 %d 次定时触发(ITIMER_REAL,间隔 1.5 秒)\n", count);
    if (count >= 3) {
        printf("已触发 3 次,取消定时器并退出\n");
        // 取消 ITIMER_REAL 定时器
        struct itimerval cancel_timer = {{0, 0}, {0, 0}};
        setitimer(ITIMER_REAL, &cancel_timer, NULL);
        exit(EXIT_SUCCESS);
    }
}

int main() {
    // 1. 捕获 SIGALRM 信号
    if (signal(SIGALRM, sigalrm_handler) == SIG_ERR) {
        perror("signal 注册失败");
        return 1;
    }

    // 2. 配置定时器参数:首次 1.5 秒,重复间隔 1.5 秒
    struct itimerval timer;
    // 重复间隔:1 秒 + 500000 微秒 = 1.5 秒
    timer.it_interval.tv_sec = 1;
    timer.it_interval.tv_usec = 500000;
    // 首次定时:1.5 秒
    timer.it_value.tv_sec = 1;
    timer.it_value.tv_usec = 500000;

    // 3. 设置 ITIMER_REAL 定时器
    if (setitimer(ITIMER_REAL, &timer, NULL) == -1) {
        perror("setitimer 失败");
        return 1;
    }
    printf("ITIMER_REAL 定时器已启动(1.5 秒重复)\n");

    // 4. 等待信号
    while (1) {
        pause();
    }
    return 0;
}
sh 复制代码
# 1. 编译程序
gcc setitimer_real.c -o setitimer_real

# 2. 运行程序
./setitimer_real

输出结果

复制代码
ITIMER_REAL 定时器已启动(1.5 秒重复)
第 1 次定时触发(ITIMER_REAL,间隔 1.5 秒)
第 2 次定时触发(ITIMER_REAL,间隔 1.5 秒)
第 3 次定时触发(ITIMER_REAL,间隔 1.5 秒)
已触发 3 次,取消定时器并退出
实例 2:ITIMER_VIRT 类型------用户态 0.5 秒定时(仅统计用户态时间)
c 复制代码
#include <stdio.h>
#include <sys/time.h>
#include <signal.h>
#include <stdlib.h>

volatile int user_time_count = 0;

// SIGVTALRM 捕获函数(ITIMER_VIRT 触发)
void sigvtalrm_handler(int sig) {
    user_time_count++;
    printf("用户态时间累积 0.5 秒,触发第 %d 次信号\n", user_time_count);
    if (user_time_count >= 2) {
        printf("用户态总时间已达 1 秒,程序退出\n");
        exit(EXIT_SUCCESS);
    }
}

int main() {
    // 1. 捕获 SIGVTALRM 信号
    if (signal(SIGVTALRM, sigvtalrm_handler) == SIG_ERR) {
        perror("signal 注册失败");
        return 1;
    }

    // 2. 配置 ITIMER_VIRT 定时器:用户态每累积 0.5 秒触发
    struct itimerval timer;
    timer.it_interval = (struct timeval){0, 500000}; // 重复间隔 0.5 秒
    timer.it_value = (struct timeval){0, 500000};    // 首次 0.5 秒
    if (setitimer(ITIMER_VIRT, &timer, NULL) == -1) {
        perror("setitimer 失败");
        return 1;
    }
    printf("ITIMER_VIRT 定时器已启动(用户态每 0.5 秒触发)\n");

    // 3. 执行用户态计算(模拟用户态耗时操作)
    printf("开始执行用户态计算...\n");
    unsigned long long sum = 0;
    while (1) {
        sum++; // 纯用户态操作,累积用户态时间
    }
    return 0;
}

编译与运行命令

bash 复制代码
gcc setitimer_virt.c -o setitimer_virt
./setitimer_virt

预期输出

复制代码
ITIMER_VIRT 定时器已启动(用户态每 0.5 秒触发)
开始执行用户态计算...
用户态时间累积 0.5 秒,触发第 1 次信号
用户态时间累积 0.5 秒,触发第 2 次信号
用户态总时间已达 1 秒,程序退出

关键结论:ITIMER_VIRT 仅统计用户态时间------若进程因 I/O 阻塞进入睡眠(非用户态),计时会暂停;只有进程执行用户代码时,时间才会累积,适合精准统计用户态代码的运行时长。

四、alarm 与 setitimer 的对比与相互影响

alarm 和 setitimer(尤其是 ITIMER_REAL 类型)在功能上存在重叠,但在精度、灵活性和适用场景上差异显著。同时,两者存在相互影响,使用时需特别注意避免冲突。

1. 核心功能对比

对比维度 alarm 函数 setitimer 函数(ITIMER_REAL) setitimer 函数(ITIMER_VIRT/ITIMER_PROF)
精度 秒级(最低 1 秒) 毫秒级(理论 1 微秒,实际 10~100 微秒) 毫秒级
定时类型 仅真实时间(墙钟时间) 真实时间 用户态时间 / 用户态+核心态时间
重复定时 需手动在信号处理函数中重新调用 支持自动重复(通过 it_interval 设置) 支持自动重复
触发信号 SIGALRM SIGALRM SIGVTALRM / SIGPROF
参数复杂度 简单(仅需秒数) 复杂(需配置 struct itimerval) 复杂
适用场景 简单秒级定时(如超时提醒、基础定时任务) 高精度真实时间定时(如高频任务调度、精准超时控制) 进程 CPU 时间监控(如性能分析、CPU 时间限制)
优点 使用简单、代码侵入性低 精度高、支持自动重复、功能灵活 精准统计 CPU 时间、不受系统负载影响
缺点 精度低、不支持自动重复 参数复杂、受系统负载影响精度 仅统计 CPU 时间、不适合真实时间定时

2. 相互影响:不可同时使用的场景

核心冲突:alarm 与 ITIMER_REAL 共享 SIGALRM 信号

alarm 函数和 setitimer 的 ITIMER_REAL 类型均通过 SIGALRM 信号触发,且共享同一内核定时器资源------若进程同时使用两者,会产生以下冲突:

  • 覆盖冲突 :调用 alarm(seconds) 会覆盖已设置的 ITIMER_REAL 定时器,反之亦然;例如,先通过 setitimer 设置 ITIMER_REAL 定时,再调用 alarm(5),原 ITIMER_REAL 定时器会被取消;
  • 信号混淆SIGALRM 信号触发后,进程无法区分是来自 alarm 还是 ITIMER_REAL,可能导致逻辑错误;
  • 精度丢失:alarm 是秒级精度,会降低 ITIMER_REAL 的毫秒级精度优势。

解决方法 :同一进程中,禁止同时使用 alarm 函数和 ITIMER_REAL 类型的 setitimer;若需高精度定时,优先使用 setitimer(ITIMER_REAL);若需简单定时,使用 alarm,二者择一。

无冲突场景 :alarm 与 ITIMER_VIRT/ITIMER_PROF 无冲突------这两种 setitimer 类型分别触发 SIGVTALRMSIGPROF 信号,与 alarm 的 SIGALRM 信号独立,可同时使用。

冲突演示:alarm 覆盖 ITIMER_REAL 定时器
c 复制代码
#include <stdio.h>
#include <sys/time.h>
#include <signal.h>
#include <unistd.h>
#include <stdlib.h>

void sigalrm_handler(int sig) {
    printf("捕获到 SIGALRM 信号(来自 alarm,而非 ITIMER_REAL)\n");
    exit(EXIT_SUCCESS);
}

int main() {
    signal(SIGALRM, sigalrm_handler);

    // 1. 先设置 ITIMER_REAL 定时器(1.5 秒触发)
    struct itimerval timer = {
        {0, 0},         // 仅一次定时,无重复
        {1, 500000}     // 1.5 秒后触发
    };
    if (setitimer(ITIMER_REAL, &timer, NULL) == -1) {
        perror("setitimer 失败");
        return 1;
    }
    printf("已设置 ITIMER_REAL 定时器(1.5 秒后触发)\n");

    // 2. 1 秒后调用 alarm(2),覆盖 ITIMER_REAL
    sleep(1);
    alarm(2);
    printf("1 秒后调用 alarm(2),覆盖 ITIMER_REAL 定时器\n");

    // 等待信号
    while (1) {
        pause();
    }
    return 0;
}
复制代码
已设置 ITIMER_REAL 定时器(1.5 秒后触发)
1 秒后调用 alarm(2),覆盖 ITIMER_REAL 定时器
捕获到 SIGALRM 信号(来自 alarm,而非 ITIMER_REAL)

结论:ITIMER_REAL 定时器被 alarm 覆盖,最终触发的 SIGALRM 来自 alarm,证明二者存在冲突,不可同时使用。

五、定时器使用的常见错误与解决方法

在使用 alarm 或 setitimer 时,易因参数配置、信号处理或类型选择错误导致定时失效、程序崩溃等问题。以下是高频错误及解决方法:

常见错误 问题现象 原因分析 解决方法
未捕获定时器信号,程序被终止 定时器触发后,程序无任何提示直接退出,终端显示"Terminated" 定时器触发的信号(如 SIGALRM、SIGVTALRM)默认处理动作是"终止进程",若进程未捕获或忽略这些信号,会被系统终止 1. 必须通过 signalsigaction 注册信号捕获函数,自定义信号处理逻辑; 2. 示例: if (signal(SIGALRM, handler) == SIG_ERR) { perror("signal 失败"); } 3. 若无需处理信号,可忽略信号(不推荐,可能丢失定时事件): signal(SIGALRM, SIG_IGN);
setitimer 参数结构体初始化错误 定时器未按预期触发(如定时时间偏差大、不重复触发),或 setitimer 调用失败 1. 未初始化 struct itimervalstruct timeval,存在垃圾数据(如 tv_usec 为负数或超过 999999); 2. 混淆 it_intervalit_value 的作用(如将重复间隔设为 it_value,导致仅触发一次); 3. tv_usec 取值超出范围(应在 0~999999 之间) 1. 显式初始化结构体,避免垃圾数据: struct itimerval timer = {``{1, 0}, {2, 0}};(推荐)或 memset(&timer, 0, sizeof(timer)); 2. 明确参数含义: - it_value:首次触发时间(必须设置,否则定时器不生效); - it_interval:重复间隔(0 表示仅一次); 3. 确保 tv_usec 取值合法(0 ≤ tv_usec ≤ 999999),避免整数溢出
alarm 重复定时时未重新调用 alarm 定时器仅触发一次,后续无信号触发 alarm 是"一次性"定时器,触发后自动失效;若需重复定时,需在信号捕获函数中重新调用 alarm(seconds),否则仅触发一次 在 SIGALRM 信号捕获函数中重新设置 alarm,实现重复定时: void handler(int sig) { alarm(1); /* 其他逻辑 */ } 注意:重新调用的时间应与预期间隔一致,避免累积误差
定时器精度低于预期(如毫秒级定时偏差大) setitimer(ITIMER_REAL) 设置 100ms 定时,实际触发间隔为 120~150ms,偏差超过 20% 1. 系统负载过高:高负载时,内核调度延迟,信号无法及时送达; 2. 进程阻塞:进程因 I/O、sleep 等操作阻塞,错过信号处理时机; 3. 硬件精度限制:部分嵌入式系统或老旧硬件的时钟精度不足,无法支持毫秒级定时 1. 降低系统负载:关闭无用进程,减少资源竞争; 2. 避免进程长时间阻塞:使用非阻塞 I/O,减少 sleep 调用; 3. 选择合适的定时类型:若需精准 CPU 时间统计,改用 ITIMER_VIRT/ITIMER_PROF(不受系统负载影响); 4. 硬件层面优化:在嵌入式系统中,选择高精度时钟硬件(如 RTC 实时时钟)
同时使用 alarm 和 ITIMER_REAL,导致定时混乱 定时器触发时间与预期不符,或信号处理逻辑错乱(无法区分信号来源) alarm 和 ITIMER_REAL 共享 SIGALRM 信号和内核定时器资源,同时使用会相互覆盖,导致定时逻辑混乱 1. 同一进程中禁止同时使用 alarm 和 ITIMER_REAL,二者择一; 2. 若需高精度定时,优先使用 setitimer(ITIMER_REAL);若需简单秒级定时,使用 alarm; 3. 若需同时处理真实时间和 CPU 时间定时,使用 setitimer(ITIMER_REAL) + setitimer(ITIMER_VIRT),避免使用 alarm

六、定时器的实际应用场景

定时器在 UNIX 程序开发中应用广泛,尤其在服务端程序、性能监控、嵌入式系统中,是实现定时任务、超时控制的核心工具。以下是典型应用场景:

1. 服务端程序的超时控制

服务端程序(如 Web 服务器、数据库)在处理客户端请求时,需设置超时时间(如 30 秒无响应则断开连接),避免因客户端异常导致资源长期占用。

实现方案

  • 使用 setitimer(ITIMER_REAL, ...) 设置超时时间(如 30 秒);
  • 客户端请求处理完成前,若收到 SIGALRM 信号,判定为超时,关闭连接并释放资源;
  • 请求正常处理完成后,取消定时器(设置 it_value 为 {0, 0})。

优势:ITIMER_REAL 的毫秒级精度可实现精准超时控制,避免误判;自动重复定时可简化多请求场景的超时管理。

2. 定时任务调度

系统工具或应用程序需定期执行任务(如日志轮转、数据备份、状态上报),需通过定时器实现周期性触发。

实现方案

  • 简单场景(秒级间隔):使用 alarm 函数,在 SIGALRM 捕获函数中重新调用 alarm,实现重复定时;
  • 复杂场景(毫秒级间隔、多任务):使用 setitimer(ITIMER_REAL),通过不同信号(如 SIGALRM、SIGVTALRM)区分不同定时任务;
  • 示例:日志系统每隔 1 小时轮转日志,通过 setitimer 设置 ITIMER_REAL 定时,触发后执行日志重命名和压缩逻辑。

优势:无需额外线程,通过信号异步触发,不阻塞主流程,资源占用低。

3. 性能监控与分析

性能分析工具(如 gprof)需统计程序的 CPU 时间占用(用户态、核心态),或定期采样程序运行状态,用于定位性能瓶颈。

实现方案

  • 统计用户态时间:使用 setitimer(ITIMER_VIRT, ...),定时触发 SIGVTALRM 信号,记录当前执行的函数栈;
  • 统计总 CPU 时间:使用 setitimer(ITIMER_PROF, ...),同时记录用户态和核心态时间占比;
  • 示例:性能工具每隔 10ms 采样一次函数调用栈,通过 ITIMER_VIRT 定时实现,生成 CPU 占用热力图。

优势:ITIMER_VIRT/ITIMER_PROF 精准统计 CPU 时间,不受系统负载影响,是性能分析的核心工具。

4. 嵌入式系统的实时控制

嵌入式系统(如工业控制、智能家居)需实时响应外部事件(如传感器数据采集、设备控制),需毫秒级甚至微秒级定时。

实现方案

  • 高精度定时:使用 setitimer(ITIMER_REAL, ...),结合硬件时钟,实现 10~100 微秒级定时;
  • 任务调度:通过多个定时器(如 ITIMER_REAL 用于设备控制,ITIMER_VIRT 用于数据处理),实现多任务并发调度;
  • 示例:温度传感器每隔 500ms 采集一次数据,通过 setitimer(ITIMER_REAL) 定时触发采集逻辑。

优势:setitimer 的高精度和灵活类型,满足嵌入式系统的实时性需求,资源占用低,适合资源受限的场景。

UNIX 系统中两种核心定时器(alarm 和 setitimer)的使用方法、参数配置、类型差异,对比了二者的优缺点和适用场景,分析了常见错误与解决方法,并介绍了实际应用场景。alarm 函数简单易用,适合秒级普通定时;setitimer 函数功能强大,支持毫秒级精度和多种计时类型,适合高精度、复杂定时场景。

在实际开发中,需根据需求选择合适的定时器:

  • 简单秒级定时(如超时提醒)→ 选择 alarm 函数,代码简洁;
  • 高精度真实时间定时(如服务端超时控制)→ 选择 setitimer(ITIMER_REAL);
  • CPU 时间统计(如性能监控)→ 选择 setitimer(ITIMER_VIRT/ITIMER_PROF);
  • 禁止同时使用 alarm 和 ITIMER_REAL,避免信号和定时器冲突。

掌握定时器的使用,是编写高效、健壮 UNIX 程序的基础,尤其在服务端开发和嵌入式领域,定时器是实现定时任务、超时控制、性能监控的核心工具。

相关推荐
名誉寒冰2 小时前
# 深入理解Linux内核与用户态通信:Netlink机制实战
linux·服务器·windows
翻斗花园牛图图-2 小时前
Linux网络编程——UdpServer
服务器
薰衣草23332 小时前
linux-1
linux·运维·服务器
egoist20232 小时前
[linux仓库]System V 进程通信详解:System V消息队列、信号量
linux·c语言·消息队列·pv·信号量
Archie_IT3 小时前
「深入浅出」嵌入式八股文—P2 内存篇
c语言·开发语言·数据结构·数据库·c++·算法
Lenyiin3 小时前
《 Linux 点滴漫谈: 三 》Linux 的骨架:文件系统与目录结构的完整图谱
linux·运维·服务器·lenyiin
ZLRRLZ3 小时前
【Linux操作系统】进程概念
linux·运维·服务器
XCOSnTh4 小时前
单片机入门的相关工具XCOSnTh
c语言·单片机·嵌入式硬件·xcosnth·单片机入门
byte轻骑兵4 小时前
Windows 安全分割利器:strtok_s () 详解
c语言·开发语言·windows·安全