您的位置:首页 > 运维架构 > Linux

Linux驱动中delayed_workqueue使用:

2018-01-26 17:10 711 查看

在驱动中,有时不能使用中断(这种情况很少遇到),此时delayed_workqueue就可以发挥其巨大的功效了。也可以用其它同类的内核API实现:如timer.delayed_workqueue的使用过程如下:

(1)定义workqueue: struct workqueue_struct *test_workqueue; //  kernel/workqueue.c

(2)定义workqueue要做的delayed工作:struct delayed_work test_delayed_work;// include/linux/workqueue.h

(3)初始化workqueue:INIT_DELAYED_WORK(&test_delayed_work,test_workqueue_func); //定义在:include/linux/workqueue.h

(4) 创建线程queue并加以名字:test_workqueue = create_singlethread_workqueue("name_of_this_queue");

(5)运行queue:queue_delayed_work(test_workqueue, &test_delayed_work, delay_time); //定义在:kernel/workqueue.c, 其中delay_time是延迟多少时间来运行queue。

注: 在test_workqueu_func中一定要再次将delayed_workqueue加入queue中,即再次运行queue_delayed_work。否则,此queue只运行一次。

下面详细讲解每个函数。

#define INIT_DELAYED_WORK(_work, _func)             \  

    do {                            \  
        INIT_WORK(&(_work)->work, (_func));      \  
        init_timer(&(_work)->timer);         \  
    } while (0)  

#define INIT_DELAYED_WORK(_work, _func)				\
do {							\
INIT_WORK(&(_work)->work, (_func));		\
init_timer(&(_work)->timer);			\
} while (0)


#define INIT_WORK(_work, _func)                     \  

    do {                                \  

        (_work)->data = (atomic_long_t) WORK_DATA_INIT();    \  
        INIT_LIST_HEAD(&(_work)->entry);         \  
        PREPARE_WORK((_work), (_func));             \  
    } while (0)  
#endif  
  
// WORK_DATA_INIT() == 0;  
// PREPARE_WORK((_work), (_func)) == (_work)->func = (_func);  
  
struct delayed_work {  
    struct work_struct work;  
    struct timer_list timer;  
};  

#define INIT_WORK(_work, _func)						\
do {								\
(_work)->data = (atomic_long_t) WORK_DATA_INIT();	\
INIT_LIST_HEAD(&(_work)->entry);			\
PREPARE_WORK((_work), (_func));				\
} while (0)
#endif

// WORK_DATA_INIT() == 0;
// PREPARE_WORK((_work), (_func)) == (_work)->func = (_func);

struct delayed_work {
struct work_struct work;
struct timer_list timer;
};
INIT_WORK的主要工作是data赋值为0; 初始化entry链表;将_func传给work的_func。

#define init_timer(timer) init_timer_key((timer), NULL, NULL)  

#define init_timer(timer) init_timer_key((timer), NULL, NULL)

init_timer_key((timer), NULL, NULL) --> debug_time_init [ NOP]

使用delayed workqueue最主要的是调用queue_delayed_work。如果delay = 0,则直接调用:queue_work 其具体实现过程:queue_work --> queue_work_on --> __queue_work --> insert_work

如果delay !=0,则调用:queue_delayed_work_on

 其具体实现过程:queue_delayed_work_on 此函数是通过timer来完成最后的延时工作。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: