Linux设备驱动中的阻塞与非阻塞I/O 及 等待队列的使用说明

时间:2022-12-05 07:53:40

s注:文章上写的是异步通知,只能通知,不能传递数据;

1、什么是阻塞I/O?

阻塞(zu se)I/O是指在执行设备操作时,若不能获得资源(不能得到使用权限),则进程被挂起,进入睡眠状态,知道条件满足后,才被唤醒;

2、什么是非阻塞I/O?

非阻塞是指执行设备操作时,若不能获得资源,则放弃或者不停的查询。若不放弃,则直到获得资源才继续下一步;

3、什么是等待队列?

等待队列(阻塞I/O)为基础数据结构,与进程调度机制紧密结合,实现内核中的异步事件的通知机制,也可以用来同步对系统资源的访问。


等待队列函数及使用方法:

1、定义等待队列头

等待队列队头    wait_queue_head_t 

等待队列初始化等待队列头init_waitqueue_head(& head_t);

2、自定义等待队列(可选)

定义等待队列DECLARE_WAITQUEUE(name, task)

添加等待队列 void add_wait_queue(wait_queue_head_t *q, wait_queue_t *wait)   

删除等待队列 void remove_wait_queue(wait_queue_head_t *q, wait_queue_t *wait)  

3、等待队列的使用

a、等待事件发生

有条件睡眠:

linux-2.6定义在/drivers/staging/rt2860/rt_linux.h中,用的宏定义

//如果condition判断为假,则进入睡眠状态

wait_even(head_t, condition);//普通等待,只能被其他进程唤醒,condition 是一个判断事件发生的一个条件语句,如(x > 0);

twait_event_interruptible(head_t, condition);//可以被中断唤醒的等待,中断唤醒时,返回-ERESTARTSYS

wait_event_timeout(head_t, condition, timeout);//可以被超时唤醒的等待,超时唤醒时,返回-ERESTARTSYS ,timeout为超时值 long

  wait_event_interruptible_timeout(head_t, condition, timeout);//可以被超时、中断唤醒的等待,当被中断或者超时唤醒时,返回-ERESTARTSYS

无条件睡眠

linux-2.6定义在 /kernel/sched.c

void __sched sleep_on(wait_queue_head_t *q) //直接进入睡眠状态

long __sched sleep_on_timeout(wait_queue_head_t *q, long timeout) //可以被超时唤醒;

void __sched interruptible_sleep_on(wait_queue_head_t *q) //可以被中断唤醒;

long __sched interruptible_sleep_on_timeout(wait_queue_head_t *q, long timeout)  //可以被中断或者超时唤醒;

b、唤醒队列

inux-2.6定义在 /inculde/linux/wait.h 

wake_up(wait_queue_head_t *q) //普通唤醒所有等待队列成员

wake_up_interruptible(wait_queue_head_t *q) //中断唤醒所有等待队列成员