首先,学习一下设备的阻塞与非阻塞操作:
阻塞操作是指,在执行设备操作时,若不能获得资源,则进程挂起直到满足可操作的条件再进行操作,被挂起的进程进入sleep 状态,被从调度器的运行队列移走,直到等待的条件被满足。非阻塞操作的进程在不能进行设备操作时,并不挂起,它或者放弃,或者不停地查询,直到可以进行操作为止。
阻塞从字面上听起来似乎意味着低效率,实则不然。如果设备驱动不阻塞,则用户想获得设备资源只能不停地查询,这反而会耗费CPU资源。而阻塞访问时,不能获得资源的进程将进行休眠,它将CPU资源让给其他进程。
在linux驱动程序中,使用等待队列(wait queue)来实现阻塞进程的唤醒。。 wait queue很早就作为一个基本的功能单位出现在 Linux内核里了,它以队列为基础数据结构,与进程 调度机制紧密结合,能够用于实现核心的异步事件通知机制。等待队列可以用来同步对系统资源的访问, Linux信号量在内核中也是由等待队列来实现的。
1、定义并初始化:
(1)
wait_queue_head_t my_queue;
init_waitqueue_head(&my_queue);
直接定义并初始化。init_waitqueue_head()函数会将自旋锁初始化为未锁,等待队列初始化为空的双向循环链表。
(2)
DECLARE_WAIT_QUEUE_HEAD(my_queue);
定义并初始化,相当于(1)。
(3)定义等待队列:
DECLARE_WAITQUEUE(name,tsk);
3、等待事件:
(1)wait_event()宏: