linux内核学习——工作队列
由于CPU要处理中断,而且中断都要求尽快执行结束,所以对于大量的程序处理都会放到下半部去执行。常用的下半部有:软中断、任务队列、工作队列等。
其中工作队列是一个比较好用,也比较常用的方法。
工作队列使用时我觉得一般会有以下几部分来共同使用。
struct workqueue_struct my_wq; //工作队列,用于通知工作者工作 struct work_struct my_work; //工作者,用于处理具体的工作任务 struct list_head my_list; //任务链表,用于存放工作任务 spinlock_t my_spin_lock; //自旋锁,用于线程间同步
如下是一个例子(未编译,可能会有瑕疵):
my_workqueue.c
#include "my_workqueue.h" #include "public.h" struct workqueue_struct *my_wq; //工作队列,用于通知工作者工作 struct work_struct my_work; //工作者,用于处理具体的工作任务 struct list_head my_work_list; //任务链表,用于存放工作任务 spinlock_t my_spin_lock; //自旋锁,用于线程间同步 //定义任务结构体 typedef struct req { struct list_head list; char * data; }req_t; void init(void) { my_wq = create_singlethread_workqueue("my_workqueue"); if (NULL == my_wq) { DBG_PRINT("Failed to alloc memory"); return ; } INIT_WORK(&my_work, handle_work); spin_lock_init(my_spin_lock); } void exit(void) { flush_workqueue(my_wq); destroy_workqueue(my_wq); } void proc_req(req_t * req) { DBG_PRINT("I am req %s", req->data); //这里需要释放内存,防止内存泄露 my_free(req); return ; } void handle_work(struct work_struct *work) { unsigned long flags = 0; req_t *req = NULL; (void)work; //消除编译告警 spin_lock_irqsave(my_spin_lock, flags); while (trur) { list_remove_head(my_work_list, req, req_t, list); if (NULL == req) { spin_unlock_irqrestore(my_spin_lock, flags); return ; } proc_req(req); } return ; } void create_work(void) { req_t *req = NULL; char data[] = "hello"; req = malloc(sizeof(req_t)); if (NULL == req) { DBG_PRINT("Failed to alloc memory"); return ; } req.data = my_alloc(sizeof(data)); memset(req.data, 0, sizeof(data)); //正常使用的话数据应该是从外部传进来的。这里只是模拟 memcpy(req.data, data, sizeof(data)); spin_lock_irqsave(my_spin_lock, flags); list_add_tail(&req.list, &my_work_list); spin_unlock_irqrestore(my_spin_lock, flags); queue_work(my_wq, &my_work); return; }
public.h
#ifndef __PUBLIC_H #define __PUBLIC_H #define uint8 unsigned char #define uint16 unsigned short #define uint32 unsigned int #define uint64 unsigned long #define DBG_PRINT printf //定义自己的打印函数 extern void my_alloc(uint32 size) { //自己定义内存申请函数 } extern void my_free(char *) { //自己定义内存释放函数 } #endif //__PUBLIC_H
关于内核的内存管理可以参考另一篇博文:http://blog.csdn.net/wangyuling1234567890/article/details/17324171