Chinaunix首页 | 论坛 | 博客
  • 博客访问: 162743
  • 博文数量: 40
  • 博客积分: 2010
  • 博客等级: 大尉
  • 技术积分: 355
  • 用 户 组: 普通用户
  • 注册时间: 2008-11-27 18:05
文章分类
文章存档

2011年(1)

2010年(9)

2009年(16)

2008年(14)

我的朋友

分类: LINUX

2008-12-05 12:45:38

7.4. 内核定时器
 

#include <linux/timer.h>
struct timer_list
{
        /* ... */
        unsigned long expires;//期望运行的 jiffies 值
        void (*function)(unsigned long);
        unsigned long data;//传给function的参数
};//使用前必须初始化
void init_timer(struct timer_list *timer);

//初始化一个timer_list
struct timer_list TIMER_INITIALIZER(_function, _expires, _data);
//初始化一个静态的timer_list
void add_timer(struct timer_list * timer);
int mod_timer(struct timer_list *timer, unsigned long expires);

int del_timer(struct timer_list * timer); 
int del_timer_sync(struct timer_list *timer);

//同 del_timer 一样,但保证函数返回时,定时器函数不在任何 CPU 上运行

//避免在SMP 系统上竞争
int timer_pending(const struct timer_list * timer);

//返回真或假来指示是否定时器已被调试运行

 

7.5. Tasklets 机制

#include <linux/interrupt.h>
struct tasklet_struct {
 /* ... */

void (*func)(unsigned long);
 unsigned long data;
};

void tasklet_init(struct tasklet_struct *t,
 void (*func)(unsigned long), unsigned long data);

//将定义好的结构体初始化,才可用

DECLARE_TASKLET(name, func, data);

//直接申明就可用了

DECLARE_TASKLET_DISABLED(name, func, data);
void tasklet_disable(struct tasklet_struct *t);

void tasklet_disable_nosync(struct tasklet_struct *t);
//对正在运行的tasklet无效,当它返回时,这个 tasklt 被禁止并且不会在以后被调度,直到重新使能.

void tasklet_enable(struct tasklet_struct *t);
//如果这个 tasklet 已经被调度, 它会很快运行. 一个对 tasklet_enable 的调用必须匹配每个对 tasklet_disable 的调用, 因为内核跟踪每个 tasklet 的"禁止次数".

void tasklet_schedule(struct tasklet_struct *t);
//调度 tasklet 执行.一般只运行一次,但可在一个tasklet中再调用,到达多次运行的目的

void tasklet_hi_schedule(struct tasklet_struct *t);
//调度 tasklet 在更高优先级执行.高于一般的tasklet优先级

void tasklet_kill(struct tasklet_struct *t);

//当一个设备正被关闭或者模块卸载时,被调用。若tasklet被调度,则从激活的链表中去掉 tasklet.若tasklet在另一个 CPU 上运行,则阻塞等待tasklet终止. 

注意:tasklet是不可中断的,一个tasklet只在一个CPU上运行

 

7.6. 工作队列

linux/workqueue.h

非共享队列

步骤:
1.创建工作队列
struct workqueue_struct *create_workqueue(const char *name);
struct workqueue_struct *create_singlethread_workqueue(const char *name);
2.创建工作
DECLARE_WORK(name, void (*function)(void *), void *data);
//一个函数搞定定义和初始化

INIT_WORK(struct work_struct *work, void (*function)(void *), void *data);
PREPARE_WORK(struct work_struct *work, void (*function)(void *), void *data);
//要先定义work_struct,再调用这两个函数

//INIT_WORK做更全的初始化,若需要改变工作队列,则用PREPARE_WORK

3.提交工作给一个工作队列
int queue_work(struct workqueue_struct *queue, struct work_struct *work);
int queue_delayed_work(struct workqueue_struct *queue, struct work_struct *work, unsigned long delay);
//返回0,添加成功,非0表明已存在此工作
int cancel_delayed_work(struct work_struct *work);

//返回非0,取消成功,返回0,取消不成功,工作仍在运行
void flush_workqueue(struct workqueue_struct *queue);
//确保cancel_delayed_work调用返回0后,停止运行工作
4.
void destroy_workqueue(struct workqueue_struct *queue);

//用完后删掉工作队列

共享队列
1.创建工作
   同非共享
2.提交工作给一个工作队列
int schedule_work(struct work_struct *work);
int schedule_delayed_work(struct work_struct *work, unsigned long delay);
//
void flush_scheduled_work(void);
//刷新 同flush_workqueue一样
 
注意:工作队列可休眠
 
阅读(1762) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~