Chinaunix首页 | 论坛 | 博客
  • 博客访问: 177462
  • 博文数量: 30
  • 博客积分: 2010
  • 博客等级: 大尉
  • 技术积分: 440
  • 用 户 组: 普通用户
  • 注册时间: 2008-07-23 19:45
文章分类

全部博文(30)

文章存档

2016年(2)

2010年(3)

2009年(8)

2008年(17)

我的朋友

分类: LINUX

2008-08-06 16:30:49

    等待队列,我对他的简单解释就是,他是一个循环链表,每个节点中包
含了一个指向等待进程
task_struct的指针。等待队列需要一个等待队列
头,作为等待队列的起始点。

所以我们现来看看等待队列头,其定义在/include/linux/wait.h中:

 50struct __wait_queue_head { 51 spinlock_t lock; 52 struct list_head task_list; 53}; 54typedef struct __wait_queue_head wait_queue_head_t; 有两个数据字段: lock:防止双向链表被同时访问,所以要使用锁。 task_list:双向链表。 然后再来看等待队列如何被定义的: 28typedef struct __wait_queue wait_queue_t; 32struct __wait_queue { 33 unsigned int flags; 34#define WQ_FLAG_EXCLUSIVE 0x01 35 void *private; 36 wait_queue_func_t func; 37 struct list_head task_list; 38}; 来看看各个字段的用意吧: flags:101表示互斥进程由内核有选择地唤醒,0表示非互斥
进程总是由内核在事件发生时唤醒。
private:此字段以前为struct task_struct * task,现在改为void *型,但
其作用不变,指向一个等待进程。
func:指向一个函数地址,被用来指定一个在等待队列的睡眠进程如何被
唤醒。
task_list:双向链表。 知道了他们的结构,我们来看一张图吧,这张图说明了他们之间的关系。 着就是他们各自的定义以及初始化: 等待队列头: 1struct wait_queue_head_t q_head;//定义 init_waitqueue_head(&q_head);//初始化 //init_waitqueue_head(my_queue);代码如下: 13void init_waitqueue_head(wait_queue_head_t *q) 14{ 15 spin_lock_init(&q->lock); 16 INIT_LIST_HEAD(&q->task_list); 17} 2、快速定义并初始化(静态地)
DECLARE_WAIT_QUEUE_HEAD(name);
源码如下: 74#define DECLARE_WAIT_QUEUE_HEAD(name) \ wait_queue_head_t name = __WAIT_QUEUE_HEAD_INITIALIZER(name) #define __WAIT_QUEUE_HEAD_INITIALIZER(name) {\ .lock = __SPIN_LOCK_UNLOCKED(name.lock), \ .task_list= { &(name).task_list, &(name).task_list } } 等待队列: 静态地定义并初始化: DECLARE_WAITQUEUE(name, tsk) 67#define DECLARE_WAITQUEUE(name, tsk) 68wait_queue_t name = __WAITQUEUE_INITIALIZER(name, tsk) 62#define __WAITQUEUE_INITIALIZER(name, tsk) {\ 63 .private = tsk, \ 64 .func = default_wake_function,\ 65 .task_list = { NULL, NULL } } 定义和初始化之后就是对他的基本操作了 一、添加等待队列:add_wait_queue(); //linux/kernel/wait.c 124static inline void __add_wait_queue(wait_queue_head_t *head, wait_queue_t *new) 125{ 126 list_add(&new->task_list, &head->task_list); 127} 21void fastcall add_wait_queue(wait_queue_head_t *q, wait_queue_t *wait) 22{ 23 unsigned long flags; 24 25 wait->flags &= ~WQ_FLAG_EXCLUSIVE; 26 spin_lock_irqsave(&q->lock, flags); 27 __add_wait_queue(q, wait); 28 spin_unlock_irqrestore(&q->lock, flags); 29} 解释:add_wait_queue()将非互斥进程添加到等待队列头所指的等待队
列中(看代码
25行,将wait->flags置为0),若想添加互斥进程则使
void fastcall add_wait_queue_exclusive(wait_queue_head_t *q,
wait_queue_t *wait),
此函数将wait->flags置为1
(源码为:
wait->flags|=WQ_FLAG_WXCLUSIVE;) 二、移除等待队列: remove_wait_queue();//linux/kernel/wait.c 43void fastcall remove_wait_queue(wait_queue_head_t *q, wait_queue_t *wait) 44{ 45 unsigned long flags; 46 47 spin_lock_irqsave(&q->lock, flags); 48 __remove_wait_queue(q, wait); 49 spin_unlock_irqrestore(&q->lock, flags); 50} 138static inline void __remove_wait_queue(wait_queue_head_t *head, 139 wait_queue_t *old) 140{ 141 list_del(&old->task_list); 142} 以上操作只是描述了等待队列本身的一些操作,并非是利用他来实现
管理任务的。
阅读(2151) | 评论(1) | 转发(0) |
给主人留下些什么吧!~~

chinaunix网友2008-08-06 22:39:20

言简意赅,说明了等待队列的本质含义。