linux 内核 工作队列
来源:互联网 发布:路易十六知乎 编辑:程序博客网 时间:2024/04/30 11:45
工作队列是将操作延期执行的另一种手段。
每个工作队列都有一个数组,数组项的数目与系统中处理器的数目相同。 每个数组项都列出了将延期执行的任务。
对每个工作队列来说,内核都会创建一个新的内核守护进程,延期任务使用等待队列机制,在该守护进程的上下文中执行。
新的工作队列通过调用 create_workqueue 或 create_workqueue_singlethread 函数来创建。前一个函数在所有CPU 上都创建一个工作线程,
而后者只在系统第一个CPU 上创建一个线程。
kernel/workqueue.c
struct workqueue_struct *__create_workqueue(const char *name, int singlethread)
name 表示创建的守护进程在进程列表中显示的名称。
所有推送到工作队列上的任务,都必须打包为 workstruct 结构的实例, 从工作队列用户的角度来看,该结构的下述成员比较重要。
workqueue.h
struct work_struct;
typedef void (*work_func_t)(struct work_struct *work);
struct work_struct {
atomic_long_t data;
struct list_head entry;
work_func_t func;
};
内核提供了 INIT_WORK(work, func) 宏, 它向一个现存的work_struct 实例提供一个延期执行函数。
有两种方法可以向一个工作队列添加 work_struct 实例,分别是 queue_work 和 queue_work_delayed
/**
* queue_work - queue work on a workqueue
* @wq: workqueue to use
* @work: work to queue
*
* Returns 0 if @work was already on a queue, non-zero otherwise.
*
* We queue the work to the CPU on which it was submitted, but if the CPU dies
* it can be processed by another CPU.
*
* Especially no such guarantee on PREEMPT_RT.
*/
int queue_work(struct workqueue_struct *wq, struct work_struct *work)
{
int ret = 0, cpu = raw_smp_processor_id();
ret = queue_work_on(cpu, wq, work);
return ret;
}
它将work 添加到工作队列 wq, work 本身所指定的工作,其执行时间待定(在调度器选择该守护进程时执行)
为确保排队的工作项将在提交后一段时间内执行,需要扩展work_struct, 添加一个定时器。
struct delayed_work {
struct work_struct work;
struct timer_list timer;
};
queue_delayed_work() 用于向工作队列提交 delayed_work 实例。 它确保在延期工作执行之前,至少经过由delay 指定的一段时间(以jiffies 为单位。)
/**
* queue_delayed_work - queue work on a workqueue after delay
* @wq: workqueue to use
* @dwork: delayable work to queue
* @delay: number of jiffies to wait before queueing
*
* Returns 0 if @work was already on a queue, non-zero otherwise.
*/
int queue_delayed_work(struct workqueue_struct *wq,
struct delayed_work *dwork, unsigned long delay)
{
if (delay == 0)
return queue_work(wq, &dwork->work);
return queue_delayed_work_on(-1, wq, dwork, delay);
}
该函数首先创建一个内核定时器,它将在delayed jiffies 之内超时。 相关的处理程序接下来使用queue_work, 按通常的方式将工作添加到工作队列。
内核创建了一个标准的工作队列,成为events。 内核中凡是没有必要创建独立的工作队列,均可使用该队列。 内核提供了以下两个函数,可用于将新的工作添加到标准队列。
/**
* schedule_work - put work task in global workqueue
* @work: job to be done
*
* Returns zero if @work was already on the kernel-global workqueue and
* non-zero otherwise.
*
* This puts a job in the kernel-global workqueue if it was not already
* queued and leaves it in the same position on the kernel-global
* workqueue otherwise.
*/
int schedule_work(struct work_struct *work)
{
return queue_work(keventd_wq, work);
}
/**
* schedule_delayed_work - put work task in global workqueue after delay
* @dwork: job to be done
* @delay: number of jiffies to wait or 0 for immediate execution
*
* After waiting for a given time this puts a job in the kernel-global
* workqueue.
*/
int schedule_delayed_work(struct delayed_work *dwork,
unsigned long delay)
{
return queue_delayed_work(keventd_wq, dwork, delay);
}
- linux 内核 工作队列
- Linux内核工作队列
- Linux内核:工作队列
- Linux 内核工作队列
- Linux内核:工作队列
- linux内核工作队列
- linux内核的工作队列
- tasklet、工作队列 - [linux内核]
- Linux内核机制:工作队列
- 论linux内核工作队列
- Linux内核中的工作队列
- 内核中工作队列(linux工作队列)
- 内核中工作队列(linux工作队列)
- 内核中工作队列(linux工作队列)
- linux内核分析之工作队列
- Linux内核中工作队列的操作
- Linux内核实践之工作队列
- linux内核知识之工作队列(workqueue)
- javascript用正则表达式过滤空格
- Thinking in java学习1
- 主引导扇区
- UVALive 3363 String Compression
- 学习python
- linux 内核 工作队列
- ssh-keygen
- Android开发心得-ListView的监听事件
- 总结一下什么外链会导致网站排名下降
- HDU 1864 Brave Game 【组合游戏,SG函数】
- android适配各种分辨率的问题
- ffmpeg编码延时问题解决
- DB2中的虚拟表
- 130804组队练习赛ZOJ校赛