LDD3学习9--数据类型和定时器
这部分对应的是第七章和第十一章,因为内容也不是很多,就一起写了。里面的内容基本上就是一个个的点,所以也就一个个点简单总结一下。
1 数据类型
1.1 数据长度

不同操作系统类型长度可能不一样,看图的话最好用u8,u16,u32,u64。
内存页最好使用PAGE_SIZE,而不要使用4K,因为很多平台可能不是4K。
1.2 字节序大小端
这个在网络编程涉及到也很多,用的时候查一下就知道了。
1.3 数据对齐
书里面说的是最后加一个__attribute__ ((packed)) scsi;,这个是取消对齐,不过我记得在一般常用的时候,都是手动指定对齐:
struct BitFieldStruct {unsigned int a : 4; // 占用 4 位unsigned int b : 3; // 占用 3 位unsigned int c : 1; // 占用 1 位
};
具体用的时候再看吧。。
1.4 判断指针
不要用NULL,用ERR_PTR,IS_ERR,PTR_ERR。
1.5 链表
这个不用自己搞,用内核里面的<linux/list.h>
2 定时器
内核通过定时器中断来跟踪时间的流动,大部分平台运行在 100 或者 1000 中断每秒; 流行的 x86 PC 缺省是 1000。
2.1 定时器
一般用的是 jiffies定时器,是在<linux/jiffies.h>。用法就不多写了,要用的时候搜一下或者GPT,答案都很标准。
高进度的定时器,可以用TSC,例子是:
unsigned long ini, end;
rdtscl(ini); rdtscl(end);
printk("time lapse: %li\n", end - ini);
两者的区别:
| 特性 | TSC 定时器 | jiffies 定时器 |
|---|---|---|
| 依赖硬件 | 依赖 CPU 硬件支持 | 不依赖硬件,完全由内核实现 |
| 精度 | 纳秒级 | 毫秒级 |
| 性能 | 非常高效 | 开销较小,但需依赖时钟中断 |
| 多核一致性 | 可能存在问题 | 无多核一致性问题 |
| 功耗 | 较高(高频访问可能增加功耗) | 较低(只在时钟中断时更新) |
| 时间跨度 | 通常不适合长时间跨度 | 可用于长时间跨度(只需考虑溢出) |
| 典型场景 | 高精度时间戳,性能测量,延迟计算 | 调度、内核延迟、一般计时需求 |
2.2 当前时间
获取当前时间,时间戳,这些和应用层好像差不多,就不多说了。
延迟,在应用层,基本上就是一个sleep打天下。在内核好像东西多了不少。
long wait_event_interruptible_timeout(wait_queue_head_t *q, condition, signed long timeout);这个是用在条件变量。
signed long schedule_timeout(signed long timeout);这个会让当前任务进行休眠,但是会被唤醒,比如信号量。
例子:
#include <linux/jiffies.h>
#include <linux/sched.h>
#include <linux/delay.h>void example_function(void) {long timeout = msecs_to_jiffies(100); // 将100毫秒转换为jiffiesset_current_state(TASK_INTERRUPTIBLE); // 设置当前任务状态为可中断睡眠schedule_timeout(timeout); // 让当前任务睡眠指定的时间
}
ndelay,udelay,mdelay。这几个都是让CPU空转,会占用很多CPU资源。所以只能用在短时间。
msleep。基于调度器调度,不会占用太多CPU资源。
2.3 内核定时器
定义是在<linux/timer.h>,让内核在指定时间后执行某个任务,某个事件或函数。通过timer_list结构,使用 init_timer() 或 timer_setup() 初始化定时器。 使用 add_timer() 启动定时器。 使用 del_timer() 删除定时器。
例子:
void setup_my_timer(void) {timer_setup(&my_timer, my_timer_callback, 0);my_timer.expires = jiffies + msecs_to_jiffies(1000); // 设置定时1秒add_timer(&my_timer);
}
2.4 Tasklets机制
Tasklets 是 Linux 内核中一种轻量级的底半部(Bottom Half)机制,专门用于在软中断(SoftIRQ)上下文中执行延迟处理任务。它可以延迟执行某些非时间敏感的任务,而不会阻塞中断处理程序(Top Half)。
这里有一个例子:
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/interrupt.h>MODULE_LICENSE("GPL");
MODULE_AUTHOR("Your Name");
MODULE_DESCRIPTION("Simple Tasklet Example");// Tasklet 函数
void my_tasklet_func(unsigned long data) {printk(KERN_INFO "Tasklet executed! Data: %lu\n", data);
}// 定义 Tasklet,初始化时指定执行函数和参数
DECLARE_TASKLET(my_tasklet, my_tasklet_func, 42);// 模块加载时调用
static int __init tasklet_example_init(void) {printk(KERN_INFO "Tasklet example module loaded.\n");// 调度 Tasklettasklet_schedule(&my_tasklet);printk(KERN_INFO "Tasklet scheduled.\n");return 0;
}// 模块卸载时调用
static void __exit tasklet_example_exit(void) {// 确保 Tasklet 在卸载前被销毁tasklet_kill(&my_tasklet);printk(KERN_INFO "Tasklet example module unloaded.\n");
}module_init(tasklet_example_init);
module_exit(tasklet_example_exit);
运行结果如下:
[553563.141606] Tasklet example module loaded. //insmod
[553563.141615] Tasklet scheduled.
[553563.141618] Tasklet executed with data: 42
[553595.066381] Tasklet example module unloaded. //rmmod
看看代码就基本明白,tasklet其实就是将任务提交给CPU调度。比如说收到一个网络包,中断处理中收到包,之后还有繁琐的解包操作,如果还是占用中断,会阻塞其它任务。这个是可以调用tasklet来处理,不用全部占用CPU,提高系统整体性能。
这样中断的前半部分就是硬中断,后半部分就是软中断,tasklet这些。
例子:
irqreturn_t my_interrupt_handler(int irq, void *dev_id)
{// 检查中断源是否来自预期设备if (check_device_irq(irq)) {// 读取设备状态寄存器unsigned int status = read_device_status();// 清除中断标志clear_device_irq(irq);// 做一些简单的处理,如将数据从设备缓冲区拷贝到内存的临时位置copy_data_from_device();// 触发中断下半部处理schedule_delayed_work(&my_work, msecs_to_jiffies(10));return IRQ_HANDLED;}return IRQ_NONE;
}
2.5 工作队列
在#include <linux/workqueue.h>中。create_workqueue,create_singlethread_workqueue,DECLARE_WORK,INIT_WORK,PREPARE_WORK。。。
说实话之前也没用过这个,查了一下,本质上就是优先级更低的tasklet,可以被内核调度,适用于耗时更长,可以阻塞的任务。不过貌似现在要被kthread替代了。
最后:之前知乎看到一篇写定时器的,写的哇塞:C/C++中如何稳定地每隔5ms执行某个函数?
相关文章:
LDD3学习9--数据类型和定时器
这部分对应的是第七章和第十一章,因为内容也不是很多,就一起写了。里面的内容基本上就是一个个的点,所以也就一个个点简单总结一下。 1 数据类型 1.1 数据长度 不同操作系统类型长度可能不一样,看图的话最好用u8,u16&…...
一文夯实垃圾收集的理论基础
如何判断一个引用是否存活 引用计数法 给对象中添加一个引用计数器,每当有一个地方引用它,计数器就加 1;当引用失效,计数器就减 1;任何时候计数器为 0 的对象就是不可能再被使用的。 优点:可即刻回收垃圾&a…...
OpenWRT Conserver 共享串口服务实现
安装驱动 查看当前可在线安装的USB驱动 opkg update 查看安装的USB驱动 opkg list-installed *usb-serial* 查看所有的USB串口驱动 opkg list *usb-serial* 确认console线的芯片厂商 kmod-usb-serial-pl2303 - 5.15.167-1 - Kernel support for Prolific PL2303 USB-to…...
第12章:Python TDD完善货币加法运算(一)
写在前面 这本书是我们老板推荐过的,我在《价值心法》的推荐书单里也看到了它。用了一段时间 Cursor 软件后,我突然思考,对于测试开发工程师来说,什么才更有价值呢?如何让 AI 工具更好地辅助自己写代码,或许…...
Springboot项目Jackson支持多种接收多种时间格式
前言 在springboot项目中经常会使用Jackson框架,当前端给后端传输时间类型时,我们一般需要先配置好时间格式,否则后端无法接收。以下是一些配置方法 统一配置 spring:jackson:time-zone: GMT+8date-format: yyyy-MM-dd HH:mm:ss这种配置就是要求前端统一传输的格式是yyyy-…...
两台电脑互PING不通的解决办法
当两台电脑无法通过网络Ping通时,可以按照以下步骤进行排查和解决: 一. 检查网络连接 确保两台电脑连接到同一个局域网。 如果是通过网线连接,检查网线是否松动或损坏。 如果是无线连接,确保Wi-Fi信号正常。 二. 检查IP配置 确…...
No. 34 笔记 | Python知识架构与数据类型相关内容 | 实操
在今天的Python学习中,我对Python的知识架构有了更深入的理解,同时也对Python的数据类型及其操作有了全面的认识和实践。 一、Python知识架构理解 Python是一门功能强大且应用广泛的编程语言,其知识架构可以从多个层面来理解。 从整体结构上…...
【2024年华为OD机试】 (B卷,100分)- 字符串分割(Java JS PythonC/C++)
一、问题描述 题目解析 问题描述 给定一个非空字符串 s,要求将该字符串分割成若干子串,使得每个子串的 ASCII 码值之和均为“水仙花数”。具体要求如下: 若分割不成功,则返回 0;若分割成功且分割结果不唯一,则返回 -1;若分割成功且分割结果唯一,则返回分割后子串的数…...
Pix2Pix :用于图像到图像转换的条件生成对抗网络
1. 背景与问题 图像到图像的转换(Image-to-Image Translation)是计算机视觉中的一个重要任务,指的是在输入一张图像的情况下,生成一张风格、内容或其他条件不同但语义一致的图像。随着深度学习的发展,尤其是生成对抗网…...
基于VSCODE+GDB+GDBSERVER远程单步调试设备篇(可视化界面)
目录 说明 配置方法 1)VSCODE必备插件 2)配置launch.json文件,用于GDB调试 调试步骤 目标板运行程序 1)已启动程序,通过attach方式进入调试 2)通过gdbserver启动时加载程序(程序路径根据实际情…...
CamemBERT:一款出色的法语语言模型
摘要 预训练语言模型在自然语言处理中已无处不在。尽管这些模型取得了成功,但大多数可用模型要么是在英语数据上训练的,要么是在多种语言数据拼接的基础上训练的。这使得这些模型在除英语以外的所有语言中的实际应用非常有限。本文探讨了为其他语言训练…...
0基础跟德姆(dom)一起学AI 自然语言处理18-解码器部分实现
1 解码器介绍 解码器部分: 由N个解码器层堆叠而成每个解码器层由三个子层连接结构组成第一个子层连接结构包括一个多头自注意力子层和规范化层以及一个残差连接第二个子层连接结构包括一个多头注意力子层和规范化层以及一个残差连接第三个子层连接结构包括一个前馈全连接子层…...
我的创作纪念日——我与CSDN一起走过的365天
目录 一、机缘:旅程的开始 二、收获:沿路的花朵 三、日常:不断前行中 四、成就:一点小确幸 五、憧憬:梦中的重点 一、机缘:旅程的开始 最开始开始写博客是在今年一二月份的时候,也就是上一…...
C++:bfs解决多源最短路与拓扑排序问题习题
1. 多源最短路 其实就是将所有源头都加入队列, 01矩阵 LCR 107. 01 矩阵 - 力扣(LeetCode) 思路 求每个元素到离其最近0的距离如果我们将1当做源头加入队列的话,无法处理多个连续1的距离存储,我们反其道而行之&…...
【面试题】JVM部分[2025/1/13 ~ 2025/1/19]
JVM部分[2025/1/13 ~ 2025/1/19] 1. JVM 由哪些部分组成?2. Java 的类加载过程是怎样的?3. 请你介绍下 JVM 内存模型,分为哪些区域?各区域的作用是什么?4. JVM 垃圾回收调优的主要目标是什么?5. 如何对 Jav…...
文献综述相关ChatGPT提示词分享
文献综述 ChatGPT 可以帮助提高文献综述的有效性和全面性。ChatGPT可以高效搜索和审查与宝子们课题研究相关的文献资料来源。一些给力的插件工具还可以帮助您总结复杂的研究论文并提取信息以更快更好地消化信息。合理的运用ChatGPT和GPTs可以提高文献综述的清晰度和质量&#…...
Excel 技巧14 - 如何批量删除表格中的空行(★)
本文讲如何批量删除表格中的空行。 1,如何批量删除表格中的空行 要点就是按下F5,然后选择空值条件以定位所有空行,然后删除即可。 按下F5 点 定位条件 选 空值,点确认 这样就选中了空行 然后点右键,选 删除 选中 下方…...
图片生成Prompt编写技巧
1. 图片情绪(场景氛围) 一张图片一般都会有一个情绪基调,因为作画本质上也是在传达一些情绪,一般都会借助图片的氛围去转达。例如:比如家庭聚会一般是欢乐、喜乐融融。断壁残垣一般是悲凉。还有萧瑟、孤寂等。 2.补充细…...
【STM32-学习笔记-4-】PWM、输入捕获(PWMI)
文章目录 1、PWMPWM配置 2、输入捕获配置3、编码器 1、PWM PWM配置 配置时基单元配置输出比较单元配置输出PWM波的端口 #include "stm32f10x.h" // Device headervoid PWM_Init(void) { //**配置输出PWM波的端口**********************************…...
TOSUN同星TsMaster使用入门——3、使用系统变量及c小程序结合panel面板发送报文
本篇内容将介绍TsMaster中常用的Panel面板控件以及使用Panel控件通过系统变量以及c小程序来修改信号的值,控制报文的发送等。 目录 一、常用的Panel控件介绍 1.1系统——启动停止按钮 1.2 显示控件——文本框 1.3 显示控件——分组框 1.4 读写控件——按钮 1.…...
【OSG学习笔记】Day 18: 碰撞检测与物理交互
物理引擎(Physics Engine) 物理引擎 是一种通过计算机模拟物理规律(如力学、碰撞、重力、流体动力学等)的软件工具或库。 它的核心目标是在虚拟环境中逼真地模拟物体的运动和交互,广泛应用于 游戏开发、动画制作、虚…...
C++ 基础特性深度解析
目录 引言 一、命名空间(namespace) C 中的命名空间 与 C 语言的对比 二、缺省参数 C 中的缺省参数 与 C 语言的对比 三、引用(reference) C 中的引用 与 C 语言的对比 四、inline(内联函数…...
鱼香ros docker配置镜像报错:https://registry-1.docker.io/v2/
使用鱼香ros一件安装docker时的https://registry-1.docker.io/v2/问题 一键安装指令 wget http://fishros.com/install -O fishros && . fishros出现问题:docker pull 失败 网络不同,需要使用镜像源 按照如下步骤操作 sudo vi /etc/docker/dae…...
前端开发面试题总结-JavaScript篇(一)
文章目录 JavaScript高频问答一、作用域与闭包1.什么是闭包(Closure)?闭包有什么应用场景和潜在问题?2.解释 JavaScript 的作用域链(Scope Chain) 二、原型与继承3.原型链是什么?如何实现继承&a…...
Device Mapper 机制
Device Mapper 机制详解 Device Mapper(简称 DM)是 Linux 内核中的一套通用块设备映射框架,为 LVM、加密磁盘、RAID 等提供底层支持。本文将详细介绍 Device Mapper 的原理、实现、内核配置、常用工具、操作测试流程,并配以详细的…...
【从零学习JVM|第三篇】类的生命周期(高频面试题)
前言: 在Java编程中,类的生命周期是指类从被加载到内存中开始,到被卸载出内存为止的整个过程。了解类的生命周期对于理解Java程序的运行机制以及性能优化非常重要。本文会深入探寻类的生命周期,让读者对此有深刻印象。 目录 …...
MySQL JOIN 表过多的优化思路
当 MySQL 查询涉及大量表 JOIN 时,性能会显著下降。以下是优化思路和简易实现方法: 一、核心优化思路 减少 JOIN 数量 数据冗余:添加必要的冗余字段(如订单表直接存储用户名)合并表:将频繁关联的小表合并成…...
Git 3天2K星标:Datawhale 的 Happy-LLM 项目介绍(附教程)
引言 在人工智能飞速发展的今天,大语言模型(Large Language Models, LLMs)已成为技术领域的焦点。从智能写作到代码生成,LLM 的应用场景不断扩展,深刻改变了我们的工作和生活方式。然而,理解这些模型的内部…...
第7篇:中间件全链路监控与 SQL 性能分析实践
7.1 章节导读 在构建数据库中间件的过程中,可观测性 和 性能分析 是保障系统稳定性与可维护性的核心能力。 特别是在复杂分布式场景中,必须做到: 🔍 追踪每一条 SQL 的生命周期(从入口到数据库执行)&#…...
从面试角度回答Android中ContentProvider启动原理
Android中ContentProvider原理的面试角度解析,分为已启动和未启动两种场景: 一、ContentProvider已启动的情况 1. 核心流程 触发条件:当其他组件(如Activity、Service)通过ContentR…...
