linux等待队列init_waitqueue_head

我们知道在字符设备驱动中,应用层调用read、write等系统调用终会调到驱动中对应的接口。 可以当应用层调用read要去读硬件的数据时,硬件的数据未准备好,那我们该怎么做?

一种办法是直接返回并报错,但是这样应用层要获得数据需要不断的调用read去访问硬件,进程的上下文在用户空间和内核空间不停的切换,耗费了CPU的资源,降低了系统效率。那么有没有更好的办法呢? 答案是有的,在这种情况下我们就可以利用Linux的阻塞机制,实现阻塞访问。

**

一、阻塞和非阻塞

**

阻塞操作是指在执行设备操作时若不能获得资源则挂起进程,直到满足可操作的条件后再进行操作。被挂起的进程进入休眠状态,被从调度器的运行队列移走,直到等待的条件被满足。而非阻塞操作的进程在不能进行设备操作时并不挂起,它或者放弃,或者不停地查询,直至可以进行操作为止。

**

二、等待队列

**

在 Linux 驱动程序中,可以使用等待队列(wait queue)来实现阻塞进程的唤醒。wait queue 很早就作为一个基本的功能单位出现在 Linux 内核里了,它以队列为基础数据结构,与进程调度机制紧密结合,能够用于实现内核中的异步事件通知机制。等待队列可以用来同步对系统资源的访问,信号量在内核中也依赖等待队列来实现。

希望等待特定事件的进程把自己放进合适的等待队列,并放弃控制权。因此,等待队列是一组睡眠的进程,当某一条件变为真时,由内核唤醒他们。

等待队列是一个具有头节点的双向循环链表,把所有睡眠的进程连接起来,每个节点元素都有进程相关的信息

init_waitqueue_head (&ql_spidev->slave_ready_wq);      //将自旋锁初始化为未锁,等待队列初始化为空的双向循环链表
        原型 init_waitqueue_head (__wait_queue_head x); 
wake_up_interruptible(&ql_spidev->slave_ready_wq);    //唤醒等待队列.
         如何唤醒:
                  在中断进程里加入,或者别的进程里面加入 wake_up_interruptible

status = wait_event_interruptible(ql_spidev->slave_ready_wq, spidev_get_slave_ready(ql_spidev));  //
        休眠
        所谓休眠就是让出CPU 然后并不返回
        wait_event_interruptible(wq, condition)
        condition = 0  ///休眠
        condition = 1  ///唤醒
 用 wake_up_interruptible ()唤醒后,wait_event_interruptible (wq, condition)宏,自身再检查“ condition ”这个条件以决定是返回还是继续休眠,真则返回,
        假则继续睡眠,不过这个程序中若有中断程序的话,中断来了,还是会继续执行中断函数的。只有当执行 wake_up_interruptible ()并且 condition 条件成立时才
        会把程序从队列中唤醒。
        
wait_event_interruptible 是linux驱动设计中断的重要函数,他有什么用呢?
        作用:
            1、就是进程休眠,等待中断:
            2、用在驱动里面会休眠当前的进程。

        
        struct __wait_queue_head {
            spinlock_t		lock;                         //在对 task_list 与操作的过程中,使用该锁实现对等待队列的互斥访问
            struct list_head	task_list;                //双向循环链表,存放等待的进程。
        };
        typedef struct __wait_queue_head wait_queue_head_t;
等待队列介绍:
                等待队列在linux内核中有着举足轻重的作用,很多linux驱动都或多或少涉及到了等待队列。
                Linux内核的等待队列是以双循环链表为基础数据结构,与进程调度机制紧密结合,能够用于实现核心的异步事件通知机制。它有两种数据结构:
                等待队列头( wait_queue_head_t )和等待队列项( wait_queue_t )。等待队列头和等待队列项中都包含一个 list_head 类型的域作为”连接件”。
                它通过一个双链表和把等待task的头,和等待的进程列表链接起来。
等待队列作用:
                在内核里面,等待队列是有很多用处的,尤其是在中断处理、进程同步、定时等场合。可以使用等待队列在实现阻塞进程的唤醒。它以队列为基
                础数据结构,与进程调度机制紧密结合,能够用于实现内核中的异步事件通知机制,同步对系统资源的访问等。
上一篇:关于jsp中使用jstl的问题


下一篇:ThinkPHP 3.2 用户注册邮箱验证激活帐号