linux等待佇列使用步驟

2021-05-23 23:26:28 字數 2497 閱讀 7420

編寫linux驅動程式的乙個問題是"到底如何使用等待佇列呢"

等待佇列很容易使用, 儘管它的設計很是微妙, 但你不需要知道它的內部細節, 處理等待佇列的最佳方式就是依照如下操作:

1. 宣告乙個struct wait_queue * 變數. 你需要為每乙個可以讓程序睡眠的事件預備這樣乙個變數. 這就是我建議你放在描述硬體特性資料結構中的資料項.

2. 將該變數的指標作為引數傳遞給不同的sleep_on和wake_up函式.

這相當容易. 例如, 讓我們想象一下, 當程序讀你的裝置時, 你要讓這個程序睡眠, 然後在某人向裝置寫資料後喚醒這個程序. 下面的**就可以完成這些工作

在linux驅動程式中,可以使用等待佇列(wait queue)來實現阻塞程序的喚醒。wait queue很早就作為一種基本的功能單位出現在linux核心裡了,它以隊列位基礎資料結構,與程序排程機制緊密結合,能夠用於實現核心中非同步事件通知機制。等待佇列可以用來同步對系統資源的訪問。(訊號量在核心中也依賴等待佇列來實現).

linux-2.6提供如下關於等待佇列的操作:

(1) 定義"等待佇列頭"

wait_queue_head_t my_queue;

(2) 初始化"等待佇列頭"

init_waitqueue_head(&my_queue);

定義和初始化的快捷方式:

declare_wait_queue_head(my_queue);  

(3) 定義等待佇列

declare_waitqueue(name, tsk);

定義並初始化乙個名為name的等待佇列(wait_queue_t);

(4) 新增/移除等待佇列

void fastcall add_wait_queue(wait_queue_head_t *q, wait_queue_t *wait);

void fastcall remove_wait_queue(wait_queue_head_t *q, wait_queue_t *wait);

add_wait_queue()用於將等待佇列wait新增到等待佇列頭q指向的等待佇列鍊錶中,而remove_wait_queue()用於將等待佇列wait從附屬的等待佇列頭q指向的等待佇列鍊錶中移除。

(5) 等待事件

wait_event(queue, condition);

wait_event_interruptible(queue, condition);

wait_event_timeout(queue, condition, timeout);

wait_event_interruptible_timeout(queue, condition, timeout);

等待第乙個引數queue作為等待佇列頭的等待佇列被喚醒,而且第二個引數condition必須滿足,否則阻塞。wait_event()和wait_event_interruptible()的區別在於後者可以被訊號打斷,而前者不能。加上timeout後的巨集意味著阻塞等待的超時時間,以jiffy為單位,在第三個引數的timeout到達時,不論condition是否滿足,均返回。

(6) 喚醒佇列

void wake_up(wait_queue_head_t *queue);

void wake_up_interruptible(wait_queue_head_t *queue);

上述操作會喚醒以queue作為等待佇列頭的所有等待佇列對應的程序。

wake_up()               <--->    wait_event()

wait_event_timeout()

wake_up_interruptible() <--->    wait_event_interruptible()   

wait_event_interruptible_timeout()

wake_up()可以喚醒處於task_interruptible和task_uninterruptible的程序

wake_up_interruptble()只能喚醒處於task_interruptible的程序。

(7) 在等待佇列上睡眠

sleep_on(wait_queue_head_t *q);

interruptible_sleep_on(wait_queue_head_t *q);

interruptible_sleep_on_timeout()函式

sleep_on()函式的作用就是將當前程序的狀態置成task_uninterruptible,定義乙個等待佇列,並把它新增到等待佇列頭q,直到支援獲得,q引導的等待佇列被喚醒。

interruptible_sleep_on()與sleep_on()函式類似,其作用是將目前程序的狀態置成task_interruptible,並定義乙個等待佇列,之後把它附屬到等待佇列頭q,直到資源可獲得,q引導的等待佇列被喚醒或者程序收到訊號。  

sleep_on()               <--->   wake_up() 

interruptible_sleep_on() <--->   wake_up_interruptible()

linux等待佇列使用案例

struct test dev static ssize t test read struct file filp,char user buf,size t count,loff t ppos set current state task interruptible mutex unlock dev...

linux 等待佇列

linux 核心的等待佇列是以雙迴圈鍊錶為基礎資料結構,與程序排程機制緊密結合,能夠用於實現核心的非同步事件通知機制。在這個鍊錶中,有兩種資料結構 等待佇列頭 wait queue head t 和等待佇列項 wait queue t 等待佇列頭和等待佇列項中都包含乙個 list head 型別的域...

linux 等待佇列

linux 核心的等待佇列是以雙迴圈鍊錶為基礎資料結構,與程序排程機制緊密結合,能夠用於實現核心的非同步事件通知機制。在這個鍊錶中,有兩種資料結構 等待佇列頭 wait queue head t 和等待佇列項 wait queue t 等待佇列頭和等待佇列項中都包含乙個 list head 型別的域...