等待队列学习笔记

本文介绍Linux驱动程序中的阻塞操作原理及其关键组件——等待队列的使用方法。详细解释了如何定义、初始化等待队列头,以及通过不同函数实现进程的阻塞与唤醒流程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

 

阻塞操作是指在执行设备操作时若不能获得资源则挂起进程,直到满足可操作的条件后再进行操作。驱动程序通过等待队列实现这样的能力。

定义“等待队列头”

wait_queue_head_t my_queue;

初始化“等待队列头”

init_waitqueue_head(&my_queue);

 定义与初始化

DECLARE_WAIT_QUEUE_HEAD(name);

添加/移除等待队列

void fastcall add_wait_queue(wait_queue_head_t *q,wait_queue_t *wait);

void fastcall remove_wait_queue(wait_queue_head_t *q,wait_queue_t *wait);

等待事件

wait_event(queue,condition)

wait_event_interruptible(queue,condition)

wait_event_timeout(queue,condition,timeout)

wait_event_interruptible_timeout(queue,condition,timeout)

int wait_event_killable(queue,condition)

 

驱动程序是通过阻塞其调用的进程来实现阻塞的。而进程的状态与等待队列是有关联的。

wait_event(queue,condition)此函数是通过set_current_state(TASK_UNINTERRUPTIBLE)设置进程状态的(条件为假时)

wait_event_interruptible(),将进程状态设置为TASK_INTERRUPTIBLE

wait_event_killable(queue,condition),将进程的状态设置为TASK_KILLABLE

TASK_INTERRUPTIBLE状态的进程在收到信号与中断时皆不能唤醒

TASK_KILLABLEN收到kill信号时可以被唤醒。

等待队列的系列函数一般是这样工作的,判断条件是否成立,不成立定义一个等待队列,然后将等待队列加入等待队列头,之后放置进程状态,调用schedule();再然后调用signal_pending(current)函数,使用其不打断系统函数的完全调用。设置当前进程状态为TASK_RUNNING.

 

唤醒队列

void wake_up(wait_queue_head_t *queue);

void wake_up_interruptible(wait_queue_head_t *queue);

 

wake_up()应与wait_event()或wait_event_timeout()成对使用

wake_up()应与wait_event_interruptible()或wait_event_interruptible_timeout()成对使用

 

使用步骤

a.在设备结构体中定义中增加两个等待队列头

 wait_queue_head_t r_wait;

 wait_queue_head_t w_wait;

b.在模块初始化中初始化等待队列头

 init_waitqueue_head(r_wait);

 init_waitqueue_head(w_wait);

c.在文件操作函数中定义等待队列

 DECLARE_WAITQUEUE(wait,current);

d.然后将等待队列加入等待队列头

 add_wait_queue(&dev->r_wait,&wait);

 add_wait_queue(&dev->w_wait,&wait);

有一部分驱动程序省掉了c,d两步,没有定义等待队列,只使用了队列头

e.调用等待队列函数

  如wait_event()

 也可以自己写调试函数

       用if语句判断条件

       用__set_current_state();改变进程状态

       schedule();更新进程调度表,挂起进程

       signal_pending();使其回到进程调度时,系统调用完整

       __set_current_state(TASK_RUNNING);

f.另外一个进程会用一个语句wake_up等待函数唤醒本进程,执行本进程以后的程序

 如wake_up_interruptible(w_wait);

g.删除等待队列

  remove_wait_queue(w_wait,&wait);

h.模块注销函数中删除等待队列头。

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值