工作队列

工作队列允许睡眠

创建

#define create_workqueue(name)

销毁

void destroy_workqueue(struct workqueue_struct *wq)

刷新

//ensure that any scheduled work has run to completion.
void flush_workqueue(struct workqueue_struct *wq);

执行指定
调度一个指定的任务

int schedule_work(struct work_struct *work);

struct work_struct
{
    atomic_long_t data;
    struct list_head entry;
    work_func_t func;
};

调度一个指定的延时任务

int schedule_delayed_work(struct delayed_work *work, unsigned long delay);

初始化
初始化一个任务

#define INIT_WORK(_work, _func)

初始化一个延时任务

#define INIT_DELAYED_WORK(_work, _func) 

执行
调度一个workqueue中的任务

queue_work(struct workqueue_struct *wq, struct work_struct *work);

调度一个workqueue中的延时任务

int queue_delayed_work(struct workqueue_struct *wq, struct delayed_work *work, unsigned long delay);

struct delayed_work
{
    struct work_struct work;
    struct timer_list timer;
};

取消延时任务

static inline int cancel_delayed_work(struct delayed_work *work)

举例

struct workqueue_struct *wq;
struct work_struct work;
wq = create_workqueue("workqueue");
INIT_WORK(&work, func);
queue_work(wq, &work);
destroy_workqueue(wq);

延时任务举例

struct workqueue_struct *wq;
struct delayed_work work;
wq = create_workqueue("workqueue");
INIT_DELAYED_WORK(&work, func);
queue_delayed_work(wq, &work, timeout * HZ);
cancel_delayed_work(&work);
destroy_workqueue(wq);

container_of宏
根据一个结构体变量中的一个域成员变量的指针来获取指向整个结构体变量的指针

#include <linux/kernel.h>
/** 
 * container_of - cast a member of a structure out to the containing structure 
 * @ptr:        the pointer to the member. 
 * @type:       the type of the container struct this is embedded in. 
 * @member:     the name of the member within the struct. 
 * */ 
#define container_of(ptr, type, member) ({  
    const typeof( ((type *)0)->member ) *__mptr = (ptr);  
    (type *)( (char *)__mptr - offsetof(type, member) );})

#include <linux/stddef.h>
#define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)

使用typeof获取变量member的类型
定义临时变量__mptr
将变量ptr指针赋给__mptr
__mptr转换为char*型指针
(char *)__mptr - offsetof(type, member) )求出结构体起始地址
将结构体转换为type*型

( (TYPE *)0 ) 将零转型为TYPE类型指针。结构以内存空间首地址0作为起始地址,则成员地址自然为偏移地址

原文地址:https://www.cnblogs.com/zhangxuechao/p/11709813.html