Chinaunix首页 | 论坛 | 博客
  • 博客访问: 4957865
  • 博文数量: 1696
  • 博客积分: 10870
  • 博客等级: 上将
  • 技术积分: 18357
  • 用 户 组: 普通用户
  • 注册时间: 2007-03-30 15:16
文章分类
文章存档

2017年(1)

2016年(1)

2015年(1)

2013年(1)

2012年(43)

2011年(17)

2010年(828)

2009年(568)

2008年(185)

2007年(51)

分类: LINUX

2010-06-24 13:58:11

最近项目中为了解决通信设备高速传输丢数问题,使用了工作队列的方式开多线程,然后异步读取一个缓冲buffer的方法。现在内核中多线程编程的方法基本 在实际项目中都使用过来,小总结一下。

/*
 * @Brief: 内核下软中断,定时器,推后执行,工作队列(多线程)的实现模板
 * @Author:liyangth@gmail.com
 * @ChangeLog:
 *    2008-04-27    liy    定时器,和工作队列实现
 *
 
*/


#include 
<linux/config.h>
#include 
<linux/module.h>
#include 
<linux/moduleparam.h>
#include 
<linux/init.h>


#include 
<linux/timer.h>    //内核定时器timer;
#include <linux/interrupt.h>    //tasklet
#include <linux/workqueue.h>    //工作队列


struct my_s{
    
struct timer_list my_timer;
    
struct tasklet_struct my_tlet;
    
struct workqueue_struct my_workqueue;
    
struct work_struct my_work;
}
;


struct my_s *gp_my_module;

/* call back function */
/* 内核定时器 */
void my_timer_callback_fn(unsigned long arg)
{
    
struct other_struct *data = (struct other_struct *)arg;

    mod_timer(
&gp_my_module->my_timer, jiffies + 10);    //10ms
    
    
/* just do it */

}


/* 软中断tasklet */
void my_tasklet_callback_fn(unsigned long arg)
{
    
struct other_struct *data = (struct other_struct *)arg;
    
    
/* just do it */

    
if(1){    //高优先级调度
        tasklet_hi_schedule(&gp_my_module->my_tlet);    
    }
else{    
        tasklet_schedule(
&gp_my_module->my_tlet);    
    }


}


/* 工作队列 */
/* work的函数原型是 void (*fn)(void *)
 * 所以工作队列的callback函数的定义更加灵活 
*/

void my_work_callbakc_fn(struct other_struct *arg)
{
    /* just do it */
}



_init()
{
    
struct other_struct *data;

    data 
= kmalloc(sizeof(struct other_struct), GFP_KERNEL);
    gp_my_module 
= kmalloc(sizeof(struct my_s), GFP_KERNEL);

    
/* 内核定时器 */
    init_timer(
&gp_my_module->my_timer);
    gp_my_module
->my_timer.data = (unsigned long)data;
    gp_my_module
->my_timer.function = my_timer_callback_fn;
    
//gp_my_module->my_timer.expires = j + tdelay; /* parameter */
    
    
/* 软中断tasklet */
    tasklet_init(
&gp_my_module->my_tlet, my_tasklet_callback_fn, (unsigned long)data);

    
/* 工作队列 */
    
&gp_my_module->my_workqueue = create_workqueue("mymoduleworkqueue");
    INIT_WORK(
&gp_my_module->my_work,my_work_callbakc_fn, data);

    
}


/* 卸载 */
_exit()
{
    
/* 停止内核定时器 */
    del_timer(
&gp_my_module->my_timer);

    
/* 软中断tasklet */
    tasklet_kill(
&gp_my_module->my_tlet);

    
/* 工作队列 */
    destroy_workqueue(
&gp_my_module->my_workqueue);
    
}

_开始,启动多线程,callback函数被执行,跑起来
{
    
/* 内核定时器 */
    mod_timer(
&gp_my_module->my_timer, jiffies + 10);    //10ms

    
/* 软中断tasklet */
    
if(1){    //高优先级调度
        tasklet_hi_schedule(&gp_my_module->my_tlet);    
    }
else{    
        tasklet_schedule(
&gp_my_module->my_tlet);    
    }


    
/* 工作队列 */
    queue_work(
&gp_my_module->my_workqueue, &gp_my_module->my_work);

}

阅读(835) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~