这里对Linux的工作队列(work_queue)不做深层次的挖掘,只对如何使用它以及一些简单的结构做简单地介绍。
Linux源代码(3.0.8)中和工作队列(work_queue)相关的结构主要在
include/linux/workqueue.h
这个头文件中,这里就不摘抄了。这里就直接给出例子代码,在结合稍作解释:
#include <linux/module.h>  
#include <linux/init.h>  
#include <linux/workqueue.h>static struct work_struct work;
static void work_handler(struct work_struct *data) 
 { 
 printk(“just a demo for work queue.\n”); 
 } 
static int __init workqueue_init(void) 
 { 
 printk(“init work queue demo.\n”); 
 INIT_WORK(&work, work_handler); 
 schedule_work(&work); 
 return 0; 
 } 
static void __exit workqueue_exit(void) 
 { 
 printk(“exit work queue demo.\n”); 
 } 
 MODULE_LICENSE(“GPL”); 
 MODULE_AUTHOR(“zhuqinggooogle@gmail.com”); 
 module_init(workqueue_init); 
 module_exit(workqueue_exit); 
一个简单的工作队列(work_queue)的演示就完成了。我们来编译后,insmod到系统看看:
/mnt/3520d $ insmod hi_work_queue.ko 
 init work queue demo 
 just a demo for work queue. 
从系统中rmmod看一下:
/mnt/3520d $ rmmod hi_work_queue 
 exit work queue demo. 
如果你对Linux的工作队列(work_queue)有稍微的了解,你看到这里会提问,“我们的工作队列项提交到了哪个工作队列线程上面呢?”,这就得从
schedule_work
函数入手。看一下其/** 
 * schedule_work - put work task in global workqueue 
 * @work: job to be done 
 * 
 * Returns zero if @work was already on the kernel-global workqueue and 
 * non-zero otherwise. 
 * 
 * This puts a job in the kernel-global workqueue if it was not already 
 * queued and leaves it in the same position on the kernel-global 
 * workqueue otherwise. 
 */ 
 int schedule_work(struct work_struct *work) 
 { 
 return queue_work(system_wq, work); 
 } 
 扯到
system_wq
这个全局变量,我们来看看他到底是什么。在
kernel/workqueue.c
这个文件的底部给出了定义:
system_wq = alloc_workqueue(“events”, 0, 0);
看到这就清楚了,刚才是把工作队列项提交了默认的工作线程events上的。那我们自己可以创建一个工作队列线程吗?可以把自己的工作队列项提交到上面吗?当然,可以。下面给出一个demo代码:
#include <linux/module.h>  
#include <linux/init.h>  
#include <linux/workqueue.h>static struct workqueue_struct *queue = NULL;  
static struct work_struct work;   
static void work_handler(struct work_struct *data)  
{  printk("just a demo for work queue.\n"); 
}  static int __init workqueue_init(void)  
{  queue = create_singlethread_workqueue("workqueue demo");if (!queue)  return -1;  printk("init work queue demo.\n");INIT_WORK(&work, work_handler);  queue_work("queue", &work);  return 0;    
}  static void __exit workqueue_exit(void)  
{  printk("exit work queue demo.\n");destroy_workqueue(queue);  
}  
MODULE_LICENSE("GPL");
MODULE_AUTHOR("zhuqinggooogle@gmail.com");  
module_init(workqueue_init);  
module_exit(workqueue_exit); 我们来insmod看一下:
/mnt/3520d insmodhiworkqueue.koinitworkqueuedemo.justademoforworkqueue./mnt/3520d 
 /mnt/3520d $ ps | grep “workqueue demo” 
 728 root 0 SW< [workqueue demo] 
你会发现多了一个内核线程workqueue demo,这就是我们代码中自己创建的。