免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 1354 | 回复: 0
打印 上一主题 下一主题

tasklet, kernelthread, timer and waitqueue [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2008-03-12 17:31 |只看该作者 |倒序浏览

                                                1.tasklet
tasklet是为了方便得处理中断下半部事宜而设计的.一般使用如下:
定义一个tasklet:
DECLARE_TASKLET(tasklet_name,tasklet_func,data);
//定义一个tasklet结构tesklet_name,与tasklet_func(data)函数相关联
static void tasklet_func(unsigned long data)
{
    //do the bottom half stuff here.........
}
在中断处理函数中,只需要做如下调用,就可以使tasklet在适当的时候调用:
tasklet_schedule(&tasklet_name);
DECLARE_TASKLET_DISABLED(name,function,data); //与DECLARE_TASKLET类似,但等待tasklet被使能
tasklet_enable(struct tasklet_struct *); //使能tasklet
tasklet_disble(struct tasklet_struct *); //禁用tasklet
tasklet_init(struct tasklet_struct *,void (*func)(unsigned long),unsigned long);
//类似DECLARE_TASKLET()
tasklet_kill(struct tasklet_struct *); // 清除指定tasklet的可调度位,即不允许调度该tasklet
2.在驱动中实现下半部的另外一种做法,可以利用工作队列(work queue)
work queue机制允许我们将要延后执行的任务在放在工作队列中,然后延后在由work queue产生的一个线程
中运行.
第一步:创建一个工作队列
struct workqueue_struct * wq = create_workqueue("my_work_queue");
随着我们创建一个工作队列,会有cpu个内核线程产生,名为 my_work_queue/0, my_work_queue/0....
如果只想创建一个内核线程,则使用create_signalthread_workqueue();
第二步:创建一个工作
struct work_struct my_work;
INIT_WORK(&my_work, (void (*)(void *))my_work_func, data)
第三步:为了执行工作,需要把工作放到工作队列当中去.(比如工作是一个下半部,我们可以在中断里面做这件
事情)
  
queue_work(my_work_queue, my_work);
queue_delayed_work(my_work_queue, my_work, 20);
注意,没必要为每一个用途都创建一个work_queue,内核中已经有一些创建好的work_queue供大家使用,例如名字为"event"的work_queue.
2.timer
Linux内核中定义了一个timer_list结构,我们在驱动程序中可以利用之:
struct timer_list {
       struct list_head list;
       unsigned long expires; //定时器到期时间
       unsigned long data; //作为参数被传入定时器处理函数
       void (*function)(unsigned long);
};
下面是关于timer的API函数:
增加定时器
void add_timer(struct timer_list * timer);
删除定时器
int del_timer(struct timer_list * timer);
修改定时器的expire
int mod_timer(struct timer_list *timer, unsigned long expires);
使用定时器的一般流程为:
(1)timer、编写function;
(2)为timer的expires、data、function赋值;
(3)调用add_timer将timer加入列表;
(4)在定时器到期时,function被执行;
(5)在程序中涉及timer控制的地方适当地调用del_timer、mod_timer删除timer或修改timer的expires
timer是linux内核中利用时钟中断来实现的定时器,可以方便得在内核中实现轮询
使用方法如下:
创建一个定时器:
static struct timer_list my_timer;
init_timer(&my_timer);      
my_timer.function = my_timer_func;   
my_timer.data = my_data;
然后指定timer的timeout值,然后将启动记时
cmmb_timer.expires = jiffies + HZ/50;     
add_timer(&cmmb_timer);  
如果需要轮询,则需要在my_timer_func返回前再
cmmb_timer.expires = jiffies + HZ/50;     
add_timer(&cmmb_timer);  
3.waitqueue
               
               
               
               
               
               
               
               
               

本文来自ChinaUnix博客,如果查看原文请点:http://blog.chinaunix.net/u1/59615/showart_494670.html
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP