linux中等待佇列的應用

2021-06-20 00:11:18 字數 3137 閱讀 2947

linux核心裡的等待佇列機制在做驅動開發時用的非常多,多用來實現阻塞式訪問,下面簡單總結了等待佇列的四種用法,希望對讀者有所幫助。

1. 睡眠等待某個條件發生(條件為假時睡眠):

睡眠方式:wait_event, wait_event_interruptible

喚醒方式:wake_up (喚醒時要檢測條件是否為真,如果還為假則繼續睡眠,喚醒前一定要把條件變為真)

2. 手工休眠方式一:

1)建立並初始化乙個等待佇列項

define_wait(my_wait) <==> wait_queue_t my_wait; init_wait(&my_wait);

2)將等待佇列項新增到等待佇列頭中,並設定程序的狀態

prepare_to_wait(wait_queue_head_t *queue, wait_queue_t *wait, int state)

3)呼叫schedule(),告訴核心排程別的程序執行

4)schedule返回,完成後續清理工作

finish_wait()

3. 手工休眠方式二:

1)建立並初始化乙個等待佇列項:

define_wait(my_wait) <==> wait_queue_t my_wait; init_wait(&my_wait);

2)將等待佇列項新增到等待佇列頭中:

add_wait_queue

3)設定程序狀態

__set_current_status(task_interruptible);

4)schedule()

5)將等待佇列項從等待佇列中移除

remove_wait_queue()

其實,這種休眠方式相當於把手工休眠方式一中的第二步prepare_to_wait拆成兩步做了,即prepare_to_wait <====>add_wait_queue + __set_current_status,其他都是一樣的。

4. 老版本的睡眠函式sleep_on(wait_queue_head_t *queue):

將當前程序無條件休眠在給定的等待佇列上,極不贊成使用這個函式,因為它對競態沒有任何保護機制。

一般情況下等待佇列使用是有兩個程序工作的,比如a程序待,b程序喚醒。

declare_wait_queue_head(buffer);

a:while(1)

b:while(1)

其實在核心中有種比較常用的是等待佇列 wait_quit_t。

declare_waitqueue(wait,current);

add_wait_queue(&buffer,&wait);

上次一使用add_wait_queue(&buffer,&wait)時,宕機是因為沒有使用schedule()這個函式,所以這個函式一直占用cpu所以就宕機了。

以下是做的乙個小實驗,這種其實是手動配置的方式。

#

include

#include

#include

#include

#include

#include

#include

#include

#include

static declare_wait_queue_head(myqueue)

;int hello(

void

)int h_init(

void

)void h_exit(

void

)static

int __init hdrv_init(

void

)static

void __exit hdrv_exit(

void

)module_license(

"gpl");

module_init(hdrv_init)

;module_exit(hdrv_exit)

;

linux還提供了有關等待佇列的操作,這些就是包裝過的:

1) wait_queue_head_t my_queue;    //定義等待佇列頭

2) init_waitqueue_head(&my_queue);    //初始化佇列頭

如果覺得上邊兩步來的麻煩,可以直接使用declare_wait_queue_head(name)

3) declare_waitqueue(name,tsk);    //定義等待佇列

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);

用於將等待佇列wait新增到等待佇列頭指向的等待佇列鍊錶中 。

5)  wait_event(queue, conditon);

wait_event_interruptible(queue, condition);//可以被訊號打斷

wait_event_timeout(queue, condition, timeout);

wait_event_interruptible_timeout(queue, condition, timeout);//不能被訊號打斷

queue:作為等待佇列頭的等待佇列被喚醒

conditon:必須滿足,否則阻塞

timeout和conditon相比,有更高優先順序

6)  void wake_up(wait_queue_head_t *queue);

void wake_up_interruptible(wait_queue_head_t *queue);

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

7)  sleep_on(wait_queue_head_t *q);

interruptible_sleep_on(wait_queue_head_t *q);

sleep_on作用是把目前程序的狀態置成task_uninterruptible,並定義乙個等待佇列,之後把他附屬到等待佇列頭q,直到資源可用,q引導的等待佇列被喚醒。interruptible_sleep_on作用是一樣的, 只不過它把程序狀態置為task_interruptible.

Linux中等待佇列的實現

linux中等待佇列的實現 在軟體開發中任務經常由於某種條件沒有得到滿足而不得不進入睡眠狀態,然後等待條件得到滿足的時候再繼續執行,進入執行狀態。這種需求需要等待佇列機制的支援。linux 中提供了等待佇列的機制,該機制在核心中應用很廣泛。在linux 核心中使用等待佇列的過程很簡單,首先定義乙個 ...

Linux中等待佇列機制分析

linux中等待佇列機制分析 在軟體開發中任務經常由於某種條件沒有得到滿足而不得不進入睡眠狀態,然後等待條件得到滿足的時候再繼續執行,進入執行狀態。這種需求需要等待佇列機制的支援。linux 中提供了等待佇列的機制,該機制在核心中應用很廣泛。在linux 核心中使用等待佇列的過程很簡單,首先定義乙個...

Linux中等待佇列機制分析

在軟體開發中任務經常由於某種條件沒有得到滿足而不得不進入睡眠狀態,然後等待條件得到滿足的時候再繼續執行,進入執行狀態。這種需求需要等待佇列機制的支援。linux 中提供了等待佇列的機制,該機制在核心中應用很廣泛。在linux 核心中使用等待佇列的過程很簡單,首先定義乙個wait queue head...