typedef struct wait_queue_entry wait_queue_entry_t;
wait_queue_head_t my_queue;
wait_queue_head_t是__wait_queue_head结构体的一个typedef。
struct wait_queue_head {
spinlock_t lock;
struct list_head head;
};
init_waitqueue_head(&my_queue);
而下面的DECLARE_WAIT_QUEUE_HEAD()宏可以作为定义并初始化等待队列头部的“快捷方式”
。
DECLARE_WAIT_QUEUE_HEAD (name)
#define init_waitqueue_head(wq_head)
do {
static struct lock_class_key __key;
__init_waitqueue_head((wq_head), #wq_head, &__key);
} while (0)
void __init_waitqueue_head(struct wait_queue_head *wq_head, const char *name, struct lock_class_key *key)
{
spin_lock_init(&wq_head->lock);
lockdep_set_class_and_name(&wq_head->lock, key, name);
INIT_LIST_HEAD(&wq_head->head);
}
DECLARE_WAITQUEUE(name, tsk)
该宏用于定义并初始化一个名为name的等待队列元素。
#define DECLARE_WAITQUEUE(name, tsk)
struct wait_queue_entry name = __WAITQUEUE_INITIALIZER(name, tsk)
#define __WAITQUEUE_INITIALIZER(name, tsk) {
.private = tsk,
.func = default_wake_function,
.entry = { NULL, NULL } }
struct wait_queue_entry {
unsigned int flags;
void *private;
wait_queue_func_t func;
struct list_head entry;
};
此宏函数相当于:
struct wait_queue_entry name = {
.private = tsk,
.func = default_wake_function,
.entry = { NULL, NULL } }
void add_wait_queue(wait_queue_head_t *q, wait_queue_entry *wait);
void remove_wait_queue(wait_queue_head_t *q, wait_queue_entry *wait);
add_wait_queue()用于将等待队列元素wait添加到等待队列头部q指向的双向链表中,而
remove_wait_queue()用于将等待队列元素wait从由q头部指向的链表中移除。
wait_event(queue, condition)
wait_event_interruptible(queue, condition)
wait_event_timeout(queue, condition, timeout)
wait_event_interruptible_timeout(queue, condition, timeout)
等待第1个参数queue作为等待队列头部的队列被唤醒,而且第2个参数condition必须满足,否则继续
阻塞。wait_event()和wait_event_interruptible()的区别在于后者可以被信号打断,而前者不能。加上
_timeout后的宏意味着阻塞等待的超时时间,以jiffy为单位,在第3个参数的timeout到达时,不论condition
是否满足,均返回
#define wait_event(wq_head, condition) \
do { \
might_sleep(); \
if (condition) \
break; \
__wait_event(wq_head, condition); \
} while (0)
#define __wait_event(wq_head, condition) \
(void)___wait_event(wq_head, condition, TASK_UNINTERRUPTIBLE, 0, 0, \
schedule())
#define ___wait_event(wq_head, condition, state, exclusive, ret, cmd) \
({ \
__label__ __out; \
struct wait_queue_entry __wq_entry; \
long __ret = ret; /* explicit shadow */ \
\
init_wait_entry(&__wq_entry, exclusive ? WQ_FLAG_EXCLUSIVE : 0); \
for (;; ) { \
long __int = prepare_to_wait_event(&wq_head, &__wq_entry, state);\
\
if (condition) \
break; \
\
if (___wait_is_interruptible(state) && __int) { \
__ret = __int; \
goto __out; \
} \
\
cmd; \
} \
finish_wait(&wq_head, &__wq_entry); \
__out: __ret; \
})
wait_event_interruptible(wq, condition) 休眠,直到 condition 为真;
休眠期间是可被打断的,可以被信号打断
wait_event(wq, condition) 休眠,直到 condition 为真;
退出的唯一条件是 condition 为真,信号也不好使
wait_event_interruptible_timeout
(wq, condition, timeout) 休眠,直到 condition 为真或超时;
休眠期间是可被打断的,可以被信号打断
wait_event_timeout(wq, condition, timeout) 休眠,直到 condition 为真;
退出的唯一条件是 condition 为真,信号也不好使
#define wake_up(x) __wake_up(x, TASK_NORMAL, 1, NULL)
#define wake_up_nr(x, nr) __wake_up(x, TASK_NORMAL, nr, NULL)
#define wake_up_all(x) __wake_up(x, TASK_NORMAL, 0, NULL)
#define wake_up_locked(x) __wake_up_locked((x), TASK_NORMAL, 1)
#define wake_up_all_locked(x) __wake_up_locked((x), TASK_NORMAL, 0)
wake_up :只唤醒等待队列中第一个等待的线程.
wake_up_nr :唤醒等待队列中从队列头开始的nr个等待的线程.
wake_up_all :唤醒等待队列中所有等待的线程.
#define wake_up_interruptible(x) __wake_up(x, TASK_INTERRUPTIBLE, 1, NULL)
#define wake_up_interruptible_nr(x, nr) __wake_up(x, TASK_INTERRUPTIBLE, nr, NULL)
#define wake_up_interruptible_all(x) __wake_up(x, TASK_INTERRUPTIBLE, 0, NULL)
#define wake_up_interruptible_sync(x) __wake_up_sync((x), TASK_INTERRUPTIBLE, 1)
sleep_on(wait_queue_head_t *q );
interruptible_sleep_on(wait_queue_head_t *q );
sleep_on()函数的作用就是将目前进程的状态置成TASK_UNINTERRUPTIBLE,并定义一个等待队
列元素,之后把它挂到等待队列头部q指向的双向链,sleep_on()函数应该与wake_up()成对使用,interruptible_sleep_on()应该与wake_up_interruptible()成对使用。