工作队列
- tasklet在软件中断上下文运行,所以tasklet的代码是原子的,而工作队列在特殊内核进程上下文运行,可以睡眠
- 内核代码可以请求工作队列函数执行延迟给定的时间间隔。
- tasklet可以在很短的时间间隔内执行,原子模式执行,工作队列可以更长的延迟,不用原子化
#include<linux/workqueue.h>
// 工作队列
struct workqueue_struct *create_workqueue(const char *name);//
struct workqueue_struct * create_singlethread_workqueue(const char *name);
//工作任务
DECLARE_WORK(name,void (*func)(void *),void *data);
INIT_WORK(struct work_struct *work,void (*func)(void *),void *data);
//提交工作任务到队列
int queue_work(struct workqueue_struct *queue,strut work_struct *work);
int queue_delayed_work(struct workqueue_struct *queue,struct work_struct *work,unsigned long delay);
//取消某个任务
int cancel_delayed_work(struct work_struct *work);//删除工作队列的入口项
//释放工作队列
void destory_workqueue(struct workqueue_struct *queue);
工作队列的执行函数可以睡眠,但是要注意在同一工作队列其他的工作任务的影响;不能访问用户空间,因为没有对应的用户进程,是特殊的内核线程。
而用户的线程对应内核的轻量级的进程。
进程是资源的分配的最小单位,而线程是独立执行的最小单位。
共享队列
设备驱动不创建workqueue,使用内核默认的workqueue,
schedule_work(struct work_struct *work);
int schedule_delayed_work(struct work_struct *work,unsigned long delay);
tasklet
以软件中断上下文一原子模式运行.
tasklet 可在稍后禁止与重新启用。
struct tasklet_struct{
void (*func)(unsigned long);
unsigned long data;
};
void tasklet_init(struct tasklet_struct *t,void (*func)(unsigned long),unsigned long data);
DECLARE_TASKLET(name,func,data);
内核定时器
执行函数与当前调用进程异步执行。类似与中断,原子上下文
不允许访问用户空间,没有对应的进程,也就不能使用current指针,注意不能使用休眠函数。
struct timer_list{
unsigned long expires;//expect jiffies
void (*func)(unsigned long);
unsigned long data;
};
void init_timer(struct timer_list *timer);
void add_timer(struct timer_list *timer);
void del_timer(struct timer_list *timer);
延迟执行
//长延迟
set_current_state(TASK_INITERRUPTIBLE);
schedule_timeout(delay);
//
void udelay(unsigned long usecs);//忙等待