yyg-cn

导航

INIT_DELAYED_WORK() 函数的简单理解

 
INIT_DELAYED_WORK() 函数
应用场景
在中断中处理太多的操作是非常危险的,对中断的及时响应有很大的影响,在linux中我们经常会用到INIT_DELAYED_WORK,来处理中断需要响应的操作。
函数功能
工作队列(work queue)是Linux内核中将操作延期执行的一种机制。INIT_DELAYED_WORK()是一个宏
函数位置
\kernel\include\linux\workqueue.h
 
函数原型
 
#define __INIT_DELAYED_WORK(_work, _func, _tflags)        \
 do {        \
  INIT_WORK(&(_work)->work, (_func));        \
  __setup_timer(&(_work)->timer, delayed_work_timer_fn,        \
         (unsigned long)(_work),        \
         (_tflags) | TIMER_IRQSAFE);        \
 } while (0)

 实例:

#include <linux/sched.h>
#include <linux/init.h>
#include <linux/module.h>
#include <linux/workqueue.h>
#include <linux/proc_fs.h>
#include <linux/delay.h>
#include <linux/interrupt.h>
#include <linux/kernel.h>
struct delayed_work mdwq;
struct workqueue_struct *mwq;
void delay_work_func(struct work_struct *work)
{
int i;
 
printk(KERN_INFO "%s:%d----%d,%s\n",__FUNCTION__,__LINE__,current->pid,current->comm);
for (i = 0; i < 3; i++) {
printk(KERN_ERR "%s:i=%d %d,%s\n",__FUNCTION__,i,current->pid,current->comm);
msleep(3000);
}
}
 
static int __init delay_work_init(void)
{
int ret;
int i;
mwq = create_workqueue("my workqueue");
if (!mwq) {
printk(KERN_ERR "Create workqueue failed!\n");
return 1;
}
printk(KERN_INFO "Create workqueue successful!\n");
 
INIT_DELAYED_WORK(&mdwq, delay_work_func);
 
ret = queue_delayed_work(mwq, &mdwq, 3000);
printk(KERN_INFO "first ret=%d!\n", ret);
 
for (i = 0; i < 3; i++) {
printk(KERN_INFO "%s:ret=%d,i=%d-----%d,%s\n",__FUNCTION__,ret, i,current->pid,current->comm);
msleep(1000);
}
 
ret = queue_delayed_work(mwq, &mdwq, 0);
printk(KERN_INFO "second ret=%d!\n", ret);
 
return 0;
}
 
static void __exit delay_work_exit(void)
{
int ret;
ret = cancel_delayed_work(&mdwq);
flush_workqueue(mwq);
destroy_workqueue(mwq);
printk(KERN_INFO "Exit! ret=%d\n", ret);
}
module_init(delay_work_init);
module_exit(delay_work_exit);
MODULE_LICENSE("GPL");

 输出:

Nov  9 16:01:17 witch kernel: [ 1450.932918] Create workqueue successful!
Nov  9 16:01:17 witch kernel: [ 1450.932919] first ret=1!
Nov  9 16:01:17 witch kernel: [ 1450.932919] delay_work_init:ret=1,i=0-----8305,insmod
Nov  9 16:01:18 witch kernel: [ 1451.966574] delay_work_init:ret=1,i=1-----8305,insmod
Nov  9 16:01:19 witch kernel: [ 1452.990607] delay_work_init:ret=1,i=2-----8305,insmod
Nov  9 16:01:20 witch kernel: [ 1454.014634] second ret=0!
Nov  9 16:01:29 witch kernel: [ 1463.006864] delay_work_func:15----8308,kworker/11:0
Nov  9 16:01:29 witch kernel: [ 1463.006868] delay_work_func:i=0  8308,kworker/11:0
Nov  9 16:01:32 witch kernel: [ 1466.078821] delay_work_func:i=1  8308,kworker/11:0
Nov  9 16:01:35 witch kernel: [ 1469.151040] delay_work_func:i=2  8308,kworker/11:0
Nov  9 16:01:39 witch kernel: [ 1472.223119] Exit! ret=0
特别注意:这里的delay_work_func实际上只调用一次,两次调用queue_delayed_work是检查work在不在workqueue里面,主要标黄的部分的返回值与位置。
bool queue_delayed_work(struct workqueue_struct *wq,
struct delayed_work *dwork,
unsigned long delay);
两个函数的返回值:
返回0,表示work在这之前,已经在workqueue中了
返回非0,表示work成功加入到workqueue中了
queue_delayed_work表示不是马上把work加入到workqueue中,而是延后delay(时间单位jiffies),再加入。注意它的work(dwork)要用宏(静态)DECLARE_DELAYED_WORK来定义和初始化,动态的可以用INIT_DELAYED_WORK,用法和没有延后的差不多。

posted on 2023-02-28 11:32  干饭的鸭鸭怪  阅读(2125)  评论(0编辑  收藏  举报