驱动学习之——内核等待队列的使用

本文深入探讨了Linux内核中的等待队列,重点分析了`struct wait_queue_head`及其`spinlock_t`锁和`list_head`任务列表在驱动学习中的应用。

在<linux/wait.h>中,结构体定义如下:

struct __wait_queue_head {
spinlock_t lock;

struct list_head task_list;

};
typedef struct __wait_queue_head wait_queue_head_t;


struct list_head {
struct list_head *next, *prev;
};



再来看定义并初始化一个wait_queue_head_t 的函数:
主要就是定义个一个wait_queue_head_t 的变量,然后初始化,lock初始化为unlock, task_list里面的next和pre都指向自己的list_head。

#define __WAIT_QUEUE_HEAD_INITIALIZER(name) { \
.lock = __SPIN_LOCK_UNLOCKED(name.lock), \
.task_list = { &(name).task_list, &(name).task_list } }


#define DECLARE_WAIT_QUEUE_HEAD(name) \
wait_queue_head_t name = __WAIT_QUEUE_HEAD_INITIALIZER(name)

我们再来看这个这个结构体:
struct __wait_queue {
unsigned int flags;
#define WQ_FLAG_EXCLUSIVE       0x01
struct task_struct * task;
struct list_head task_list;
};


把整个队列画出来,是这样的,中间的节点是wait_queue_t,一个等待队列包含了等待特定事件的所有进程。


在我们这样使用:
DECLARE_WAIT_QUEUE_HEAD(queue_name);
就新建并初始化了一个queue的头结点。
然后调用以下函数,就新生成了一个wait_queue_t 的节点,并加入到这个队列中,这样在等待的事情发生后,内核就可以从该队列中找到等待的进程。
wait_even(queue_name, condition);
wait_even_interruptible(queue_name, condition);
wait_even_timeout(queue_name, condition, timeout);
wait_even_interruptible_timeout(queue_name, condition);

唤醒的方法:
void wake_up(wait_queue_head_t* queue);  
void wake_up_interruptible(wait_queue_head_t* queue);
会唤醒等待的所有进程。注意我们一般都把wait_even与wake_up对应起来,wait_even_interruptible与 wake_up_interruptible对应起来。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值