實現方法
**一、手動實現**
定義乙個等待佇列頭,並初始化等待佇列頭
wait_queue_head_t wq;
init_waitqueue_head(&wq);
定義乙個等待佇列項,新增等待佇列項到等待佇列
declare_waitqueue(r_wait,current); //r_wait表示等待佇列項的名稱,current表示當前程序
add_wait_queue(&wq,&r_wait);
判斷應用層是否以阻塞方式開啟檔案
if(file->f_flags & o_nonblock)
//判斷條件不成立表示使用者是以非阻塞的方式開啟的檔案
若應用層以阻塞方式開啟檔案,切換程序的狀態
set_current_state(task_interruptible); //可中斷的等待態
主動放棄cpu,等待程序被喚醒
schedule(); //主動放棄cpu
被喚醒
//可以被訊號喚醒,也可以被中斷喚醒(被中斷喚醒表示資料已經住哪被好了)
//wake_up(x);
wake_up_interruptible(x);
喚醒後判斷是否是被訊號喚醒,如果不是訊號被喚醒,表示資料已經準備好,可以進行資料的拷貝
if(signal_pending(current))
//判斷條件不成立,表示不是被訊號喚醒的,可以進行資料的拷貝
資料拷貝前將程序狀態切換為執行狀態
set_current_state(task_running); //切換程序為執行態
拷貝資料
copy_to_user();
刪除等待佇列項
remove_wait_queue();
**一、自動實現**
定義等待佇列頭
wait_queue_head_t wq;
定義乙個標誌位,代表阻塞或者被喚醒
int condition = 0;
//condition等於0的時候表示阻塞,condition為真的時候表示被喚醒
實現阻塞
//wait_event(wq,condition);
wait_event_interrupt(wq,condition);
非阻塞的方式實現比較簡單,只需要在應用層開啟檔案時使用o_nonblock
open("/dev/char",o_rdwr|o_nonblock);
應用層用於監聽多個檔案描述符的函式有select、poll、epoll,這三個函式都呼叫驅動層的poll函式;
實現方法
定義等待佇列頭,並初始化
提交等待佇列頭
poll_wait();
當條件為真時,置位mask
pollin ------表示使用者可讀
pollout------表示使用者可寫
應用層**實現:
1.新增訊號處理函式
sighander_t signal(int signum,sighander_t hander);
2.設定訊號傳送的程序
fcntl(fd,f_setown,getpid());
3.呼叫fasync函式
flags = fcntl(fd,f_getfl);
fcntl(fd,f_setfl,flags|fasync);
Linux 字元裝置驅動模型
一。使用字元裝置驅動程式 1.編譯 安裝驅動 在linux系統中,驅動程式通常採用核心模組的程式結構來進行編碼。因此,編譯 安裝乙個驅動程式,其實質就是編譯 安裝乙個核心模組 2.建立裝置檔案 通過字元裝置檔案,應用程式可以使用相應的字元裝置驅動程式來控制字元裝置。建立字元裝置檔案的方法一般有兩種 ...
Linux字元裝置驅動 經典標準字元模型
經典標準字元模型,即為linux2.6之前的早期經典標準字元模型。沒有使用乙個核心的結構體,把需要的資訊進行封裝 安裝驅動後,不會在 dev 目錄下建立裝置節點,需要使用mknod建立。乙個主裝置號只能被註冊一次,一次註冊0 255的次裝置號就被占用了。雜項裝置,每次註冊,只占用了乙個次裝置號,主裝...
詳解協程,事件驅動模型,I O模型
什麼是事件驅動模型 協程介紹 協程是什麼 協程是微執行緒,他是一種使用者態的輕量級執行緒,它的好處是沒有執行緒切換的開銷,我們開多執行緒,執行緒的上下文切換是耗費cpu的開銷的,但是多協程裡邊,只是乙個控制流調到了另外乙個控制流,它還是單執行緒,所以協程很適合高併發,乙個cpu可以支援上萬的協程,因...