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

linux内核学习——工作队列

2014-03-19 23:38 549 查看
由于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
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: