linux wait queue詳解

來源:互聯網
上載者:User
#include <linux/wait.h> typedef int (*wait_queue_func_t)(wait_queue_t *wait, unsigned mode, int flags, void *key);int default_wake_function(wait_queue_t *wait, unsigned mode, int flags, void *key);struct __wait_queue_head {    spinlock_t lock;    struct list_head task_list;};typedef struct __wait_queue_head wait_queue_head_t; #define __WAITQUEUE_INITIALIZER(name, tsk) {                \    .private    = tsk,                        \    .func        = default_wake_function,            \    .task_list    = { NULL, NULL } } #define DECLARE_WAITQUEUE(name, tsk)                    \    wait_queue_t name = __WAITQUEUE_INITIALIZER(name, tsk) #define __WAIT_QUEUE_HEAD_INITIALIZER(name) {                \    .lock        = __SPIN_LOCK_UNLOCKED(name.lock),        \    .task_list    = { &(name).task_list, &(name).task_list } } #define DECLARE_WAIT_QUEUE_HEAD(name) \    wait_queue_head_t name = __WAIT_QUEUE_HEAD_INITIALIZER(name) #define __WAIT_BIT_KEY_INITIALIZER(word, bit)                \    { .flags = word, .bit_nr = bit, } extern void __init_waitqueue_head(wait_queue_head_t *q, struct lock_class_key *); #define init_waitqueue_head(q)                \    do {                        \        static struct lock_class_key __key;    \                            \        __init_waitqueue_head((q), &__key);    \    } while (0) void __init_waitqueue_head(wait_queue_head_t *q, struct lock_class_key *key){    spin_lock_init(&q->lock);    lockdep_set_class(&q->lock, key);    INIT_LIST_HEAD(&q->task_list);} 

操作:

1. 定義"等待隊列頭"

wait_queue_head_t my_queue;

2. 初始化"等待隊列頭"

init_waitqueue_head(&my_queue);

同時, DECLARE_WAIT_QUEUE_HEAD(name)宏可以定義並初始化等待隊列頭.

#define DECLARE_WAIT_QUEUE_HEAD(name) \    wait_queue_head_t name = __WAIT_QUEUE_HEAD_INITIALIZER(name)#define __WAIT_QUEUE_HEAD_INITIALIZER(name) {                \    .lock        = __SPIN_LOCK_UNLOCKED(name.lock),        \    .task_list    = { &(name).task_list, &(name).task_list } }

3. 定義等待隊列

DECLARE_WAITQUEUE(name, tsk)

tsk一般為當前進行current. 這個宏定義並初始化一個名為name的等待隊列.

#define DECLARE_WAITQUEUE(name, tsk)                    \    wait_queue_t name = __WAITQUEUE_INITIALIZER(name, tsk)#define __WAITQUEUE_INITIALIZER(name, tsk) {                \    .private    = tsk,                        \    .func        = default_wake_function,            \    .task_list    = { NULL, NULL } }

這時的private將會在wake_up()及其變種中使用, 最終將會預設調用default_wake_function()函數, 此函數實際上為try_to_wake_up(curr->private, mode, wake_flags);

/*** * try_to_wake_up - wake up a thread * @p: the to-be-woken-up thread * @state: the mask of task states that can be woken * @sync: do a synchronous wakeup? * * Put it on the run-queue if it's not already there. The "current" * thread is always on the run-queue (except when the actual * re-schedule is in progress), and as such you're allowed to do * the simpler "current->state = TASK_RUNNING" to mark yourself * runnable without the overhead of this. * * returns failure only if the task is already active. */static int try_to_wake_up(struct task_struct *p, unsigned int state, int wake_flags);

4. 添加/刪除等待隊列

void add_wait_queue(wait_queue_head_t *q, wait_queue_t *wait);void add_wait_queue_exclusive(wait_queue_head_t *q, wait_queue_t *wait);void remove_wait_queue(wait_queue_head_t *q, wait_queue_t *wait);

5. 等待事件

wait_event(wq, condition)wait_event_timeout(wq, condition, timeout)wait_event_interruptible(wq, condition)wait_event_interruptible_timeout(wq, condition, timeout)

6. 喚醒等待隊列

#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) #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) /** * __wake_up - wake up threads blocked on a waitqueue. * @q: the waitqueue * @mode: which threads * @nr_exclusive: how many wake-one or wake-many threads to wake up * @key: is directly passed to the wakeup function * * It may be assumed that this function implies a write memory barrier before * changing the task state if and only if any tasks are woken up. */void __wake_up(wait_queue_head_t *q, unsigned int mode,            int nr_exclusive, void *key){    unsigned long flags;     spin_lock_irqsave(&q->lock, flags);    __wake_up_common(q, mode, nr_exclusive, 0, key);    spin_unlock_irqrestore(&q->lock, flags);}

7. 在等待隊列上睡眠

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);#define __sched        __attribute__((__section__(".sched.text")))

sleep_on()函數應該與wake_up()成對使用, interrupt_sleep_on()應該與wake_up_interruptible()成對使用

#include <linux/wait.h> 
相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.