Linux Kernel 学习笔记12:定时任务

(本章基于:Linux-4.4.0-37)

内核定时器可在用户设定时间到达后调用一段任务,基本数据定义、API如下:

struct timer_list {
    unsigned long        expires;
    void            (*function)(unsigned long);
    unsigned long        data;
    ......

    ......

};

定时器基本数据类型,expires表明定时器期望jiffies所达到的值,当时间达到此值,将会调用function函数,并使用data作为参数;


void init_timer(struct timer_list *timer)

初始化定时器

int add_timer(struct timer_list *timer)

添加一个定时器到内核动态定时器链表

int del_timer(struct timer_list *timer)

注销一个定时器

int del_timer_sync(struct timer_list *timer)

和del_timer相似,但它保证在返回时,定时器函数不在任何一个CPU上执行。del_timer_sync用来避免竞争情况在SMP系统上,并在UP内核中和del_timer相同。应当优先使用del_timer_sync;

int mod_timer(struct timer_list *timer)

当一个定时器被已经被插入内核动态定时器链表,我们可以通过这个函数来修改他的的expires;


需要注意的是,这个定时器函数是被一个类似硬件中断(软中断)所触发,所以它处在中断上下文(原子上下文)中而不是进程上下文。当你处在进程上下文之外,你必须遵守下列规则:

1)没有允许存取用户空间. 因为没有进程上下文, 没有和任何特定进程相关联的到用
户空间的途径.
2)这个 current 指针在原子态没有意义, 并且不能使用因为相关的代码没有和已被
中断的进程的联系.
3)不能进行睡眠或者调度. 原子代码不能调用 schedule 或者某种 wait_event, 也
不能调用任何其他可能睡眠的函数. 例如, 调用 kmalloc(..., GFP_KERNEL) 是违
犯规则的. 旗标也必须不能使用因为它们可能睡眠。


例程:

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

#define TIMER_INTERVAL  (5 * HZ)        //5s

static struct timer_list timer;
static long unsigned int start;

static void
hello_cleanup(void)
{
        del_timer_sync(&timer);
}

void
timer_function(unsigned long arg)
{
        long unsigned int current_time = jiffies;

        printk(KERN_INFO "timer:%d\n", (int)((current_time - start) / HZ));
        mod_timer((struct timer_list*)arg, current_time + TIMER_INTERVAL);
}

static __init int hello_init(void)
{
        start = jiffies;

        init_timer(&timer);
        timer.expires = start + TIMER_INTERVAL;
        timer.function = timer_function;
        timer.data = (unsigned long)&timer;
        add_timer(&timer);

        printk(KERN_ALERT "hello init success!\n");
        return 0;
}

static __exit void hello_exit(void)
{
        hello_cleanup();
        printk(KERN_WARNING "helloworld exit!\n");
}

module_init(hello_init);
module_exit(hello_exit);

MODULE_LICENSE("GPL");
MODULE_AUTHOR("Stone");



评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

stone8761

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值