Linux 核心等待佇列解析

2021-06-28 02:29:50 字數 2697 閱讀 4324

在閱讀tun驅動時看到,有一些類似 add_wait_queue 的函式,這些函式正是執行等待佇列的相關操作,要說等待佇列還得從核心程序排程說起,核心排程系統內程序,分配時間片,但是有些程序如從網絡卡中讀資料,在網絡卡有資料到達之前程序處於阻塞狀態,如果此時給相應程序分配時間片做排程,無疑是浪費系統資源,所以系統內每個程序都有自己的狀態標誌 task->state,這些狀態定義於檔案 include/linux/sched.h

#define task_running            0

#define task_interruptible 1

#define task_uninterruptible 2

...

核心只會呼叫標誌是 task_running 的程序,如果需要等待資源,可以設定自己的程序標誌為 task_interruptible (可中斷)或者 task_uninterruptible (不可中斷),然後呼叫 schedule();放棄cpu,此程序就不會被核心排程了,但隨之而來的問題是,如果程序所需資源可以使用,如何喚醒程序呢,這就要依賴於等待佇列了,程序在放棄控制權之前,把自己加入乙個佇列中,當所需條件滿足,其他程序便可wakeup該佇列,修改程序狀態為 task_running,等待程序便可順利往下執行了。

/* 等待佇列頭宣告 */

wait_queue_head_t ******_queue;

/* 初始化等待佇列頭 */

init_waitqueue_head(&******_queue);

/* 定義等待佇列項 */

declare_waitqueue (name, tsk);

/* 新增刪除等待項 */

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

/* 喚醒等待頭中的所有項 */

void wake_up(wait_queue_head_t * queue);

void wake_up_interruptible(wait_queue_head_t * queue);

結合這些函式,再往******驅動裡新增一些簡單的機制支援等待。在 ******_read 函式中修改當前程序狀態,加入等待佇列後,放棄控制權,另加入 ******_write 函式喚醒佇列。

#include#include#include#include#include#include#include#include#include#include#includedev_t devno;

struct class * ******_class;

static struct cdev cdev;

wait_queue_head_t ******_queue; //等待佇列頭

char test_data[255];

int len;

ssize_t ******_read(struct file * pfile,

char __user * buf, size_t size, loff_t * ppos)

ssize_t ******_write(struct file * pfile, const char __user * buf, size_t count, loff_t * ppos)

if (!copy_from_user(test_data, buf, count))

return len;

}int ******_open(struct inode * pnode, struct file * pfile)

int ******_release(struct inode * pnode, struct file * pfile)

static struct file_operations ******_op =

;static int __init initialization(void)

static void __exit cleanup(void)

module_init(initialization);

module_exit(cleanup);

module_author("alloc [email protected]");

module_description("a ****** linux kernel module");

module_version("v0.2");

module_license("dual bsd/gpl");

載入模組 insmod ******.ko 後,使用cat讀取資料,cat /dev/******, 會發現程序處於等待狀態,不會輸出任何資訊,新開啟乙個終端,輸入echo 「test」 > /dev/******執行寫操作,cat便會輸出資料,緊接著再次處於等待狀態。

insmod ******.ko

cat /dev/****** ---> 程序等待

first ---> echo "first" > /dev/******

cool ---> echo "cool" > /dev/******

Linux核心等待佇列

在linux驅動程式設計中,可以使用等待佇列來實現程序的阻塞,等待佇列可看作儲存程序的容器,在阻塞程序時,將程序放入等待佇列,當喚醒程序時,從等待等列中取出程序。linux 2.6核心提供了如下關於等待佇列的操作 1 定義等待佇列 wait queue head t my queue 2 初始化等待...

linux核心等待佇列方法

當你在使用者空間需要讀寫一大片資料的時候,這個就用上了。以下來自 假設我們在 kernel 裡產生乙個 buffer,user 可以經由 read,write 等 system call 來讀取或寫資料到這個 buffer 裡。如果有乙個 user 寫資料到 buffer 時,此時 buffer 已...

Linux 裝置驅動 核心等待佇列

在 linux 驅動程式設計中,可以使用等待佇列來實現程序的阻塞.等待佇列可以看作儲存程序的容器,在阻塞程序時,將程序放入等待佇列 當喚醒程序時,從等待佇列中取出程序.linux 2.6 核心提供了如下關於等待佇列的操作 wait queue head t my queue init waitque...