Linux内核工作队列实例

29.1 前言

Linux中的工作队列是将工作推后执行的一种方式,通常用在中断分层机制中,因为中断函数的原则是(1)快;(2)不能睡眠或等待;因此,在中断驱动程序中,引入工作队列实现中断的分层,硬件处理在中断函数中处理,软件及其耗时操作则在Linux内核线程中实现。本小节,将介绍Linux内核队列及其使用方式。

29.2 工作队列特点

(1)工作队列中是可以阻塞或睡眠的;

(2)调用schedule_work(&work)后,work马上就会被调度执行;

(3)Linux工作队列属于一种异步处理机制;

(4)工作队列是通过内核进程实现的;

                                       

29.3 相关函数说明

workqueue*create_workqueue(*name)

创建工作队列;返回一个工作队列;name为工作队列名字

destroy_workqueue(struct workqueue_struct *wq)

销毁工作队列;wq为工作队列指针

queue_work(*wq,*work)

调度一个指定的工作;wq工作队列指针;work工作指针

INIT_WORK(*work,callfunc)

动态初始化工作;work为工作结构指针;callfunc为回调函数

schedule_work(*work)

工作调度;work为工作指针

schedule_delayed_work(*work,delay)

调度后延时执行;work工作指针;delay延时时间

29.4 工作队列实例

在驱动编写中,我们可以创建一个新的队列,也可以用内核已有的工作队列,这样我们就可以少去创建工作队列的代码,而直接用内核工作队列,这一般是满足我们的开发需要的。

实例1:使用内核工作队列,由内核定时器模拟中断产生调度。

#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/fs.h>
#include <linux/module.h>
#include <linux/time.h>
#include <linux/slab.h> //kmalloc头文件

#define I_DEVICE_NAME			"iTimer"
static int major;
static struct timer_list tm;

struct work_struct *work1;/*工作队列*/

void iTimer_callback(unsigned long arg)
{
	struct timeval tv;
	char *strp = (char*)arg;
	printk(KERN_EMERG "%s: %lu, %s\n", __func__, jiffies, strp);
	schedule_work(work1);

	mod_timer(&tm,jiffies+6*HZ); //每6s模拟触发一次中断调度
}

//工作队列处理函数
void work_CallBackfunc()
{
	printk(KERN_EMERG "this is second part work\n");	
}

static const struct file_operations stfops = {
	.owner	= THIS_MODULE,
};

static int __init iTest_Init(void)
{
	/* 主设备号设置为0表示由系统自动分配主设备号 */
	major = register_chrdev(0, I_DEVICE_NAME, &stfops);

	/*Linux内核定时器初始化*/
	init_timer(&tm);
	tm.function= iTimer_callback;
	tm.data = (unsigned long)"I am timer";
	tm.expires = jiffies+1*HZ;
	add_timer(&tm);

	//创建工作队列
	work1=kmalloc(sizeof(struct work_struct),GFP_KERNEL);  //第二个参数是标志
	INIT_WORK(work1,work_CallBackfunc);

	return 0;
}

static void __exit iTest_Exit(void)
{
	unregister_chrdev(major, I_DEVICE_NAME);
	del_timer(&tm);
}

module_init(iTest_Init);
module_exit(iTest_Exit);

MODULE_LICENSE("GPL");

实例2:创建新工作队列及构建工作。

static struct workqueue_struct *miki_test_wq;//声明工作队列
static struct work_struct miki_test_work;;//声明工作

/*工作处理函数*/
static void miki_test_work_callback ()
{
    //这里添加相应的逻辑,比如每隔5秒让闪关灯亮一次等
}

/*主函数*/
void mian()
{
    //创建自己的工作队列
    miki_test_wq = create_singlethread_workqueue("miki_test");
    //初始化工作,实际上是让工作work绑定工作处理函数miki_test_work_callback
    INIT_WORK(&miki_test_work, miki_test_work_callback);
    //调度执行一个指定(miki_test_wq)中的任务miki_test_work
    queue_work(miki_test_wq, &miki_test_work); 
}

 

 

 

  • 0
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值