等待队列

等待队列概念以及使用

一、概述
等待队列在内核中有很多用途,尤其在中断处理、进程同步及定时。等待队列实现事件上的条件等待;希望等待特定事件的进程把自己放在合适的等待队列,并放弃控制权。

二、相关结构体

  1. 等待队列由双向链表实现,其元素包括指向进程描述符的指针。每个等待队列都有一个等待队列头,即wait_queue_head_t结构。
    struct __wait_queue_head {
    spinlock_t lock;
    struct list_head task_list; //等待进程链表
    };
    typedef struct __wait_queue_head wait_queue_head_t;

  2. 等待队列链表中的元素,即wait_queue_t结构
    等待队列链表中的每个元素代表一个睡眠进程,进程描述符地址存入private字段中。
    typedef int (*wait_queue_func_t)(wait_queue_t *wait, unsigned mode, int flags, void *key);

struct __wait_queue {
unsigned int flags; //标志

define WQ_FLAG_EXCLUSIVE 0x01

void *private;    //进程描述符
wait_queue_func_t func;    //唤醒函数,缺省为default_wake_function
struct list_head task_list;    //链接到等待队列链表中

};
typedef struct __wait_queue wait_queue_t;

A、定义和初始化等待队列头
DECLARE_WAIT_QUEUE_HEAD(wait);//初始化一个等待队列头 wait
或者动态地, 如下:
wait_queue_head_t wait;
init_waitqueue_head(&wait);

B、休眠进程
    wait_event(wait, condition) //将当前进程的状态设置为 TASK_UNINTERRUPTIBLE
    wait_event_interruptible(wait, condition) //TASK_INTERRUPTIBLE    
    wait_event_timeout(wait, condition, timeout) //TASK_UNINTERRUPTIBLE  
    wait_event_interruptible_timeout(wait, condition, timeout) //TASK_INTERRUPTIBLE    

    备注:
        wait 是等待队列头, condition 是条件,如果调用 wait_event 前 condition == 0 ,则调用 wait_event 之后,当前           
        进程就会休眠。
        
        TASK_INTERRUPTIBLE 与 TASK_UNINTERRUPTIBLE 区别在于,它的休眠是否会被信号打断,别的进程发来一个信号比如 kill ,
        TASK_INTERRUPTIBLE 就会醒来去处理。然而 TASK_UNINTERRUPTIBLE 不会。schedule(),进程调度,而 schedule_timeout()
        进行调度之后,一定时间后自动唤醒。
        
C、唤醒进程
    void wake_up(wait_queue_head_t *wait);
    void wake_up_interruptible(wait_queue_head_t *wait);
    
    备注: 
        对应于不同的进程状态,使用不同的唤醒函数。比如你调用 wake_up 去唤醒一个使用 wait_event 等,进入休眠的进程,唤醒
        之后,它会判断 condition 是否为真,如果还是假的继续睡眠。

你可能感兴趣的:(等待队列)