首页 > 系统相关 >《Linux设备驱动开发详解(第3版)》 第9章 Linux内核定时器与工作队列

《Linux设备驱动开发详解(第3版)》 第9章 Linux内核定时器与工作队列

时间:2025-01-11 10:30:41浏览次数:3  
标签:定时器 struct work timer 内核 Linux workqueue my

9.1 内核定时器

内核定时器用于在指定的延迟时间后执行特定的函数。它在内核中常用于实现周期性任务或延迟执行的任务。

#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/timer.h>

// 定义一个内核定时器
struct timer_list my_timer;

// 定时器到期时执行的函数
void my_timer_function(unsigned long data) {
    // data 是传递给定时器处理函数的参数
    printk(KERN_INFO "My timer function called with data %ld\n", data);
    // 这里可以添加具体的任务逻辑,例如执行一些周期性的操作
    // 重新设置定时器,让其再次到期执行
    mod_timer(&my_timer, jiffies + msecs_to_jiffies(5000));
    // jiffies 是系统启动以来的节拍数,msecs_to_jiffies 将毫秒转换为节拍数,这里设置5秒后再次触发
}

// 模块初始化函数
static int __init timer_init(void) {
    // 初始化定时器
    init_timer(&my_timer);
    // 设置定时器到期时执行的函数
    my_timer.function = my_timer_function;
    // 设置传递给定时器处理函数的参数
    my_timer.data = 42;
    // 设置定时器首次到期的时间,这里设置为5秒后
    my_timer.expires = jiffies + msecs_to_jiffies(5000);
    // 添加定时器到内核定时器队列
    add_timer(&my_timer);
    printk(KERN_INFO "Timer initialized and added\n");
    return 0;
}

// 模块退出函数
static void __exit timer_exit(void) {
    // 从内核定时器队列中删除定时器
    del_timer_sync(&my_timer);
    printk(KERN_INFO "Timer removed\n");
}

module_init(timer_init);
module_exit(timer_exit);
MODULE_LICENSE("GPL");

9.2 工作队列

工作队列允许内核在进程上下文中执行延迟的任务。这意味着任务可以睡眠,并且可以访问用户空间的资源(在适当的情况下)。

#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/workqueue.h>

// 定义工作结构体
struct my_work_struct {
    struct work_struct work;
    int data;
};

// 工作处理函数
void my_work_handler(struct work_struct *work) {
    // 通过 container_of 宏从 work_struct 结构体获取包含它的 my_work_struct 结构体
    struct my_work_struct *my_work = container_of(work, struct my_work_struct, work);
    printk(KERN_INFO "My work handler called with data %d\n", my_work->data);
    // 这里可以添加具体的工作任务逻辑
}

// 模块初始化函数
static int __init workqueue_init(void) {
    struct workqueue_struct *my_wq;
    struct my_work_struct *my_work;

    // 创建一个工作队列
    my_wq = create_workqueue("my_workqueue");
    if (!my_wq) {
        printk(KERN_ERR "Failed to create workqueue\n");
        return -ENOMEM;
    }

    // 分配内存用于工作结构体
    my_work = kmalloc(sizeof(struct my_work_struct), GFP_KERNEL);
    if (!my_work) {
        destroy_workqueue(my_wq);
        printk(KERN_ERR "Failed to allocate memory for work\n");
        return -ENOMEM;
    }

    // 初始化工作结构体中的数据
    my_work->data = 10;
    // 初始化工作结构体中的 work 成员
    INIT_WORK(&my_work->work, my_work_handler);

    // 将工作提交到工作队列
    queue_work(my_wq, &my_work->work);
    printk(KERN_INFO "Work submitted to workqueue\n");
    return 0;
}

// 模块退出函数
static void __exit workqueue_exit(void) {
    // 销毁工作队列
    destroy_workqueue(my_wq);
    printk(KERN_INFO "Workqueue destroyed\n");
}

module_init(workqueue_init);
module_exit(workqueue_exit);
MODULE_LICENSE("GPL");

上述代码分别展示了内核定时器和工作队列的基本使用方法。内核定时器适合执行一些周期性或延迟的轻量级任务,而工作队列则更适合执行需要在进程上下文中完成的任务,特别是那些可能会睡眠的任务。在实际应用中,可根据具体需求选择合适的机制。

标签:定时器,struct,work,timer,内核,Linux,workqueue,my
From: https://blog.csdn.net/qq_40844444/article/details/145023520

相关文章

  • Linux IPC:管道与FIFO汇总整理
    管道(Pipes)和先进先出(FIFOs,也称为命名管道)都是Linux中用于进程间通信(IPC)的机制。它们允许数据从一个进程流向另一个进程,类似于命令行中的管道操作符|。下面详细介绍这两种机制以及如何使用它们。管道(Pipes)管道是一种特殊的文件,它允许数据从一个进程(通常称为生产者)流向另......
  • wacom 手写笔linux驱动代码
    /*Wacomprotocol4serialtabletdriverThisprogramisfreesoftware;youcanredistributeitand/ormodifyitunderthetermsoftheGNUGeneralPublicLicenseaspublishedbytheFreeSoftwareFoundation;eitherversionof2oftheLicense,or(a......
  • Arch Linux Code-OSS里面空格显示太小了
    Code-OSS是linux版本的vscode,发现在ArchLinuxCode-OSS里面空格显示太小了,网上找了很多方法,有一个ubuntu用户说是第三个一定“第三个一定是monospace”,我无意中发现,其实就是字体的问题,只要你添加的字体足够多就行了,先看一下默认字体状态下的字体显示,就是一个tab确实是4个空......
  • 文件“硬连接”是 Linux 操作系统的缺陷吗,为啥跟微软的文件“软连接”,不一致?
    故事时间假设有个女孩叫 小文件:小文件在硬盘上有个家(inode),地址是2号楼304。这个家里存着她的全部信息:身高、体重(划掉)、兴趣爱好等等。硬链接:相当于【身份证】假如小文件要办两个身份证(硬链接),每个身份证都记录着:这个人住在2号楼304。无论用哪个身份证,都能找到本人只要......
  • Linux开机启动过程
    Linux系统的开机启动过程是一个复杂但有序的序列,它确保系统从硬件初始化到提供一个完全功能的操作环境。以下是这个过程的详细步骤:BIOS/UEFI启动:当计算机加电时,首先执行的是基本输入输出系统(BIOS)或更现代的统一可扩展固件接口(UEFI)。BIOS/UEFI主要负责硬件自检(POST,Power-O......
  • 在Linux中,如何进行系统性能的持续监控?
    在Linux中进行系统性能的持续监控,需要综合运用各种命令行工具和图形化界面工具,以及自动化脚本和第三方监控平台。以下是实现持续监控的一些建议步骤和工具:1.使用基础命令行工具实时查看top:实时查看CPU使用率、内存占用、运行中的进程等基本信息。htop(一个增强版的top):提供......
  • [Linux] 包管理器之【APT】
    序续:《[Linux]Linux中安装软件的方式?-博客园/千千寰宇》《[Linux]包管理器之综述【RPM/DPKG|YUM/APT】-博客园/千千寰宇》概述:包管理器APTAPT:AdvancedPackagingTool(现名)解释:AdvancedPackagingTool(apt),作为原始包管理器DPKG的前端包管理工具(在线包管......
  • 想在linux平台拥有和vs一样的体验模式吗?只需配置一下你的vim便可以轻松达到,让你日常
            ......
  • Linux基础——kail工具
    一、nmap主机发现和端口扫描1、nmap指定源端口eth0发送扫描┌──(root㉿kali2024)-[~]└─#nmap192.168.190.110-eeth0StartingNmap7.94SVN(https://nmap.org)at2025-01-1019:56HKTNmapscanreportfor192.168.190.110Hostisup(0.0018slatency).Nots......
  • day13-Linux系统用户管理知识2
    1.passwd1.1更改密码[root@oldboy~]#passwd更改用户root的密码。新的密码:无效的密码:密码少于8个字符重新输入新的密码:passwd:所有的身份验证令牌已经成功更新。#修改其他用户的密码[root@oldboy~]#passwdoldboy更改用户oldboy的密码。新的密码......