一.概述
二.等待佇列
struct __wait_queue_head
;typedef
struct __wait_queue_head wait_queue_head_t;
因為等待佇列可以在中斷的時候進行修改,所以操作佇列之前會給佇列加上乙個自旋鎖,task_list其中是雙向佇列
struct __wait_queue
;
為了讓當前程序在乙個等待佇列中進行睡眠,需要呼叫wait_event 函式,程序進入睡眠,將控制權釋放給排程器,但是在執行了wait_event函式之中,得要有相應的能夠達到的地方進行wake_up呼叫,讓程序從沉睡狀態中進行喚醒
我們可以使用add_wait_queue函式來將乙個程序新增到等待佇列,該函式在獲得必要的自旋鎖之後,會執行__add_wait_queue函式
void
add_wait_queue
(wait_queue_head_t *q, wait_queue_t *wait)
static
inline
void
__add_wait_queue
(wait_queue_head_t *head, wait_queue_t *new)
將任務插到佇列的頭部,其中我們還可以使用一下add_wait_queue_exclusive,這個函式會將任務插到佇列的尾部,並且將標籤進行設定為wq_exclusive
void fastcall add_wait_queue_exclusive
(wait_queue_head_t *q, wait_queue_t *wait)
我們也可以同時使用prepare_to_wait.還需要程序的狀態
void fastcall
prepare_to_wait
(wait_queue_head_t *q, wait_queue_t *wait,
int state)
export_symbol
(prepare_to_wait)
;
//初始化等待分配
void
init_waitqueue_head
(wait_queue_head_t *q)
static
inline
void
init_waitqueue_entry
(wait_queue_t *q ,
struct task_struct *p)
try_to_wake_up
(struct task_struct *p,
unsigned
int state,
int wake_flags)
我們也可以使用乙個巨集來進行wait_queue_t的初始化
#define define_wait(name) \
wait_queue_t name =
在這裡我們使用了autoremove_wake_function 來進行程序的喚醒,還將等待佇列成員從等待佇列中進行刪除
int
autoremove_wake_function
(wait_queue_t *wait,
unsigned mode,
int sync,
void
*key)
但是使用的過程中,add_wait_queue 通常是不直接使用的,經常使用的是wait_event
這是乙個巨集,我們可以將其展開
___wait_event
(wq, condition, state, exclusive, ret, cmd)
cmd;
//schedule(),進入睡眠,從程序就緒佇列選擇乙個高優先順序程序來代替當前程序執行
}finish_wait
(&wq,
&__wait)
;//如果__wait還位於佇列wq,則將__wait從wq中移除
}
除此之外,核心還定義了其他的幾個函式,可以將當前程序放置於等待佇列中
#define wait_event_interruptible(wq,condition)
#define wait_event_timeout(wq,condition,timeout)
#define wait_event_interruptible_timeout(wq,condition,timeout)
wait_event_interruptible 使用的程序狀態為task_interruptible,因而睡眠程式可以通過接受訊號而被喚醒
wait_event_timeout 等待滿足指定條件,等待時間超過了指定的超時限制而停止,防止程序永久沉睡
wait_event_interruptible_timeout 讓程序睡眠,但可以通過接受訊號來進行喚醒,註冊乙個超時的時間
喚醒程序,可用於喚醒等待佇列的程序,它們基於同乙個函式
void
__wake_up
(wait_queue_head_t *q,
unsigned
int mode,
int nr_exclusive,
void
*key)
static
void
__wake_up_common
(wait_queue_head_t *q,
unsigned
int mode,
int nr_exclusive,
int wake_flags,
void
*key)
//q用於選定等待佇列,mode指定程序的狀態,用於控制喚醒程序的條件 nr_exclusive
//表示將要喚醒的設定了wq_flag_exclusive標誌的程序的資料
}
在這裡會反覆的掃瞄鍊錶,直到沒有更多的程序需要喚醒,或者已經喚醒的獨佔程序的數目達到了nr_exclusive.該限制用於避免所謂的驚群問題.如果幾個程序在等待獨佔訪問的某乙個資源,那麼同時喚醒所有等待程序應該是毫無意義的,除了其中乙個,其他程序都會再次睡眠 Linux原始碼 等待佇列注釋
linux中了等待佇列的毒,中充斥著等待佇列。不信你翻翻 等待佇列的喚醒我們這裡叫啟用。免得和執行緒喚醒混淆。頭結點wait queue head t的結構 struct wait queue head 熟悉的wait queue head t實際上是struct wait queue head t...
Linux核心等待佇列
在linux驅動程式設計中,可以使用等待佇列來實現程序的阻塞,等待佇列可看作儲存程序的容器,在阻塞程序時,將程序放入等待佇列,當喚醒程序時,從等待等列中取出程序。linux 2.6核心提供了如下關於等待佇列的操作 1 定義等待佇列 wait queue head t my queue 2 初始化等待...
linux等待佇列簡析
在閱讀tun驅動時看到,有一些類似 add wait queue 的函式,這些函式正是執行等待佇列的相關操作,要說等待佇列還得從linux核心程序排程說起,核心排程系統內程序,分配時間片,但是有些程序如從網絡卡中讀資料,在網絡卡有資料到達之前程序處於阻塞狀態,如果此時給相應程序分配時間片做排程,無疑...