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

linux 内核态和用户态定时器函数使用总结

1,场景总结

定时器类型精度范围适用场景注意事项
用户态信号定时器秒级简单任务调度、心跳检测信号处理函数中不可调用非异步安全函数
timerfd+epoll纳秒级高精度事件循环、多媒体处理需要配合IO多路复用机制使用
内核timer_list毫秒级设备驱动、硬件交互基于jiffies时钟滴答
内核hrtimer微秒级实时系统、性能监控消耗更多CPU资源
用户态传统信号定时器秒级后台日志轮转、简单心跳检测等对精度要求不高的场景需要配合IO多路复用机制使用

2,用户态使用

(1),监控日志

#include <sys/time.h>
#include <signal.h>
#include <unistd.h>void timer_handler(int sig) {static int count = 0;KEIL_LOG(KERNEL_CTRL, "Timer expired %d times\n", ++count);//printf("Timer expired %d times\n", ++count);
}int main() {struct sigaction sa;struct itimerval timer;// 设置信号处理函数sa.sa_handler = &timer_handler;sigemptyset(&sa.sa_mask);sa.sa_flags = 0;sigaction(SIGALRM, &sa, NULL);// 配置定时器(首次1秒后触发,之后每2秒触发)timer.it_value.tv_sec = 1;timer.it_value.tv_usec = 0;timer.it_interval.tv_sec = 2;timer.it_interval.tv_usec = 0;setitimer(ITIMER_REAL, &timer, NULL);while(1) pause(); // 保持进程运行return 0;
}

(2),心跳包检测

#include <sys/timerfd.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <unistd.h>#define HEARTBEAT_INTERVAL 5void send_heartbeat(int sockfd) {const char *msg = "HEARTBEAT";send(sockfd, msg, strlen(msg), 0);
}int main() {int sockfd = socket(AF_INET, SOCK_STREAM, 0);// 连接服务器代码省略...int timer_fd = timerfd_create(CLOCK_MONOTONIC, 0);struct itimerspec its = {.it_value = {.tv_sec = HEARTBEAT_INTERVAL, .tv_nsec = 0},.it_interval = {.tv_sec = HEARTBEAT_INTERVAL, .tv_nsec = 0}};timerfd_settime(timer_fd, 0, &its, NULL);while(1) {uint64_t exp;read(timer_fd, &exp, sizeof(exp));send_heartbeat(sockfd); // 每5秒发送心跳包}close(timer_fd);return 0;
}

(3)timerfd+epoll实现高精度定时器采集传感器数据

#include <sys/timerfd.h>
#include <sys/epoll.h>
#include <unistd.h>
#include <stdio.h>
#include <stdint.h>
#include <fcntl.h>
#include <string.h>#define SENSOR_PATH "/dev/temperature_sensor"  // 传感器设备路径
#define POLL_INTERVAL_MS 200                   // 采集间隔200msint read_sensor_data(int fd) {char buf[32];int ret = read(fd, buf, sizeof(buf));if(ret > 0) {printf("Sensor value: %.*s\n", ret, buf);return 0;}return -1;
}int main() {// 打开传感器设备int sensor_fd = open(SENSOR_PATH, O_RDONLY | O_NONBLOCK);if(sensor_fd == -1) {perror("open sensor failed");return -1;}// 创建定时器int timer_fd = timerfd_create(CLOCK_MONOTONIC, TFD_NONBLOCK);struct itimerspec its = {.it_interval = {.tv_sec = 0, .tv_nsec = POLL_INTERVAL_MS * 1000000},.it_value = {.tv_sec = 1, .tv_nsec = 0}  // 首次1秒后触发};timerfd_settime(timer_fd, 0, &its, NULL);// 创建epoll实例int epoll_fd = epoll_create1(0);struct epoll_event timer_ev = {.events = EPOLLIN,.data.fd = timer_fd};epoll_ctl(epoll_fd, EPOLL_CTL_ADD, timer_fd, &timer_ev);// 事件循环while(1) {struct epoll_event events[2];int n = epoll_wait(epoll_fd, events, 2, -1);for(int i=0; i<n; i++) {if(events[i].data.fd == timer_fd) {uint64_t exp;read(timer_fd, &exp, sizeof(exp));read_sensor_data(sensor_fd);  // 定时读取传感器}}}close(timer_fd);close(sensor_fd);return 0;
}

 3,内核态使用

(1)精度内核定时器(hrtimer)‌ 适合需要微秒级精度的内核任任务

#include <linux/module.h>
#include <linux/hrtimer.h>
#include <linux/io.h>#define REG_ADDR 0xFE200000  // 设备寄存器物理地址
#define CHECK_INTERVAL_NS 200000000  // 200ms间隔static struct hrtimer hr_timer;
static void __iomem *reg_map;enum hrtimer_restart timer_callback(struct hrtimer *timer) {u32 reg_value = ioread32(reg_map);printk(KERN_INFO "Device reg value: 0x%x\n", reg_value);hrtimer_forward_now(timer, ns_to_ktime(CHECK_INTERVAL_NS));return HRTIMER_RESTART;
}static int __init timer_init(void) {// 映射硬件寄存器reg_map = ioremap(REG_ADDR, sizeof(u32));if (!reg_map) {printk(KERN_ERR "Failed to map hardware register\n");return -ENOMEM;}// 初始化高精度定时器hrtimer_init(&hr_timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);hr_timer.function = &timer_callback;hrtimer_start(&hr_timer, ns_to_ktime(CHECK_INTERVAL_NS), HRTIMER_MODE_REL);printk(KERN_INFO "Hardware monitor module loaded\n");return 0;
}static void __exit timer_exit(void) {hrtimer_cancel(&hr_timer);iounmap(reg_map);printk(KERN_INFO "Module unloaded\n");
}module_init(timer_init);
module_exit(timer_exit);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("YourName");

(2)内核timer_list 使用举例

内核timer_list 基于jiffies时钟滴答使用检测看门狗举例

#include <linux/timer.h>
static struct timer_list wdt_timer;void wdt_callback(struct timer_list *t) {if(!feed_dog()) {  // 检测喂狗信号panic("Watchdog timeout!");}mod_timer(&wdt_timer, jiffies + msecs_to_jiffies(500)); // 500ms周期检测
}void init_watchdog(void) {timer_setup(&wdt_timer, wdt_callback, 0);mod_timer(&wdt_timer, jiffies + msecs_to_jiffies(500));
}

Linux内核中使用timer_stats统计定时器事件 


#include <linux/module.h>
#include <linux/timer.h>
#include <linux/proc_fs.h>static struct timer_list test_timer;
static unsigned long timeout_count;void timer_callback(struct timer_list *t) {timeout_count++;mod_timer(&test_timer, jiffies + msecs_to_jiffies(100));
}static int proc_show(struct seq_file *m, void *v) {seq_printf(m, "Timer stats:\n");seq_printf(m, "Expired count: %lu\n", timeout_count);seq_printf(m, "Current jiffies: %lu\n", jiffies);return 0;
}static int proc_open(struct inode *inode, struct file *file) {return single_open(file, proc_show, NULL);
}static const struct proc_ops proc_fops = {.proc_open = proc_open,.proc_read = seq_read,.proc_lseek = seq_lseek,.proc_release = single_release,
};static int __init timer_init(void) {timer_setup(&test_timer, timer_callback, 0);mod_timer(&test_timer, jiffies + msecs_to_jiffies(100));proc_create("timer_stats", 0, NULL, &proc_fops);return 0;
}static void __exit timer_exit(void) {del_timer_sync(&test_timer);remove_proc_entry("timer_stats", NULL);
}module_init(timer_init);
module_exit(timer_exit);
MODULE_LICENSE("GPL");

 

 

http://www.lryc.cn/news/2391922.html

相关文章:

  • 支持selenium的chrome driver更新到136.0.7103.113
  • 硬件服务器基础
  • LVS的DR模式部署
  • TRS收益互换平台开发实践:从需求分析到系统实现
  • 测试Bug篇
  • 【Linux系统移植】Cortex-A8 Linux系统移植(超详细)
  • 第十五届蓝桥杯大赛软件赛国赛Python 大学 C 组试做【本期题单: 设置密码、栈】
  • 报错SvelteKitError: Not found: /.well-known/appspecific/com.chrome.devtools.json
  • word添加页眉
  • JavaScript 中的 BigInt:当普通数字不够“大“时的救星
  • 通过mailto:实现web/html邮件模板唤起新建邮件并填写内容
  • 2025推客系统小程序开发:独立部署源码交付,高性价比裂变增长引擎
  • 【Python零基础入门系列】第6篇:Python 的数据结构世界(列表、字典、集合、元组)
  • MVCC 原理与并发控制实现
  • CentOS 7.0重置root密码
  • YOLOV11改进策略【最新注意力机制】CVPR2025局部区域注意力机制LRSA-增强局部区域特征之间的交互
  • 3D建模的全景图谱:从55个工具到元宇宙的数字革命
  • Kotlin 活动事件通讯跳转深度讲解
  • vue + ant-design + xlsx 实现Excel多Sheet页导出功能
  • 关于 Web 安全:6. 常见 CMS 开源系统风险点
  • DAY33 简单神经网络
  • OBOO鸥柏丨2025年鸿蒙生态+国产操作系统触摸屏查询一体机核心股
  • 【观成科技】Ymir勒索软件组织窃密木马RustyStealer加密通信分析
  • Vuer开源程序 是一个轻量级的可视化工具包,用于与动态 3D 和机器人数据进行交互。它支持 VR 和 AR,可以在移动设备上运行。
  • 浅谈学习(费曼学习法)
  • 高光谱成像相机:表型技术在林业育种和精确林业的应用
  • iOS App启动优化(冷启动、热启动)
  • 短视频一键搬运 v1.7.1|短视频无水印下载 一键去重
  • 海上石油钻井平台人员安全管控解决方案
  • (25年5.28)ChatGPT Plus充值教程与实用指南:附国内外使用案例与模型排行