本文将介绍下Linux中的工作队列,并给出具体的demo。
1. 为什么要有工作队列 可以参见Work Queues 。
简单来说,工作队列(work queue)是Linux kernel中将工作推后执行的一种机制。这种机制和Tasklets 不同之处在于工作队列是把推后的工作交由一个内核线程去执行,因此工作队列的优势就在于它允许重新调度甚至睡眠。
2. 数据结构 kernel version : v5.3-rc5
1 2 3 4 5 struct work_struct { atomic_long_t data; struct list_head entry ; work_func_t func; };
The work queues allow kernel functions to be activated (much like deferrable functions) and later executed by special kernel threads called worker threads .
3. demo Simple example of workqueue:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 #include <linux/init.h> #include <linux/module.h> #include <linux/workqueue.h> #include <linux/slab.h> MODULE_LICENSE("Dual BSD/GPL" ); #define printd() \ printk(KERN_ALERT "workqueue_test: %s %d\n" , __FUNCTION__, __LINE__); struct workqueue_struct *wq ; struct work_data { struct work_struct work ; int data; }; static void work_handler(struct work_struct *work) { struct work_data * data = (struct work_data *)work ; printd(); kfree(data); } static int wq_init(void ) { struct work_data * data ; printd(); wq = create_workqueue("wq_test" ); data = kmalloc(sizeof (struct work_data), GFP_KERNEL); INIT_WORK(&data->work, work_handler); queue_work(wq, &data->work); return 0 ; } static void wq_exit(void ) { printd(); flush_workqueue(wq); destroy_workqueue(wq); printd(); } module_init(wq_init); module_exit(wq_exit);
Results:
1 2 3 4 workqueue_test: wq_init 33 workqueue_test: work_handler 23 workqueue_test: wq_exit 45 workqueue_test: wq_exit 48
具体函数的api去lxr中查询。
参考资料:
Linux中的工作队列
Shan Yizhou notes:Linux Work Queue