由于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.youkuaiyun.com/wangyuling1234567890/article/details/17324171