linux内核编程之内核定时器

【版权声明:转载请保留出处:blog.csdn.net/gentleliu。邮箱:shallnew*163.com】

如果我们需要在将来某个时间点调度执行某个动作,同时在该时间点到达之前不会阻塞当前进程,可以使用内核定时器。内核定时器可用来在未来的某个特定时间点调度执行某个函数,从而可用于完成许多任务。
Linux 内核所提供的用于操作定时器的数据结构和函数(位于 <linux/timer.h>)如下
struct timer_list {
    /*
     * All fields that change during normal runtime grouped to the
     * same cacheline
     */
    struct list_head entry;        /* 定时器列表 */
    unsigned long expires;        /* 期望定时器执行的jiffies值 */
    struct tvec_base *base;

    void (*function)(unsigned long);/* 定时器处理函数 */
    unsigned long data;        /* 作为参数被传入定时器处理函数 */

    int slack;

#ifdef CONFIG_TIMER_STATS
    int start_pid;
    void *start_site;
    char start_comm[16];
#endif
#ifdef CONFIG_LOCKDEP
    struct lockdep_map lockdep_map;
#endif
};

使用定时器必须初始化,使用函数
void init_timer(struct timer_list * timer);
然后还需为定时器结构成员expires、function、data(需要的话)赋值。
使用如下函数注册定时器:
void add_timer(struct timer_list * timer);
这样定时器将在expires之后执行函数function,不过此时只能执行一次,如果想在之后每个expires时间都执行function函数的话,需要在function函数里面修改定时器expires的值。使用如下函数修改:
int mod_timer(struct timer_list *timer, unsigned long expires);
在定时器处理函数中,在做完相应的工作后,往往会延后 expires 并将定时器再次添加到内核定时器链表,以便定时器能再次被触发。

一个示例如下:
#include <linux/module.h>
#include <linux/init.h>
#include <linux/version.h>

#include <linux/timer.h>
#include <linux/delay.h>

struct timer_list   sln_timer;

void sln_timer_do(unsigned long l)
{
    mod_timer(&sln_timer, jiffies + HZ);//HZ为1秒,在此时间之后继续执行

    printk(KERN_ALERT"jiffies: %ld\n", jiffies);//简单打印jiffies的值
}

void sln_timer_set(void)
{
    init_timer(&sln_timer);//初始化定时器

    sln_timer.expires = jiffies + HZ;   //1s后执行
    sln_timer.function = sln_timer_do;    //执行函数

    add_timer(&sln_timer);    //向内核注册定时器
}

static int __init sln_init(void)
{
    printk(KERN_ALERT"===%s===\n", __func__);

    sln_timer_set();
    return 0;
}

static void __exit sln_exit(void)
{
    printk(KERN_ALERT"===%s===\n", __func__);

    del_timer(&sln_timer);//删除定时器
}

module_init(sln_init);
module_exit(sln_exit);

MODULE_LICENSE("GPL");
MODULE_AUTHOR("sln");

像定时器这种周期性的任务还可以使用延时工作队列来实现。
给一个示例:
#include <linux/module.h>
#include <linux/init.h>
#include <linux/version.h>

#include <linux/workqueue.h>
#include <linux/delay.h>

static struct workqueue_struct      *sln_wq = NULL;
static struct delayed_work          sln_dwq;


static void sln_do(struct work_struct *ws)
{
    queue_delayed_work(sln_wq, &sln_dwq, 1000);
    printk(KERN_ALERT"jiffies: %ld\n", jiffies);
}

static int __init sln_init(void)
{
    printk(KERN_ALERT"===%s===\n", __func__);

    sln_wq = create_workqueue("sln_work_queue");
    INIT_DELAYED_WORK(&sln_dwq, sln_do);
    queue_delayed_work(sln_wq, &sln_dwq, 0);

    return 0;
}

static void __exit sln_exit(void)
{
    printk(KERN_ALERT"===%s===\n", __func__);

    cancel_delayed_work(&sln_dwq);
    flush_workqueue(sln_wq);
    destroy_workqueue(sln_wq);
}

module_init(sln_init);
module_exit(sln_exit);

MODULE_LICENSE("GPL");
MODULE_AUTHOR("allen");


  • 3
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值