Linux裝置驅動程式設計之阻塞與非阻塞(轉)
Linux裝置驅動程式設計之阻塞與非阻塞(轉)[@more@] 阻塞操作是指,在執行裝置操作時,若不能獲得資源,則程式掛起直到滿足可操作的條件再進行操作。非阻塞操作的程式在不能進行裝置操作時,並不掛起。被掛起的程式進入sleep狀態,被從排程器的執行佇列移走,直到等待的條件被滿足。
在Linux驅動程式中,我們可以使用等待佇列(wait queue)來實現阻塞操作。wait queue很早就作為一個基本的功能單位出現在Linux核心裡了,它以佇列為基礎資料結構,與程式排程機制緊密結合,能夠用於實現核心的非同步事件通知機制。等待佇列可以用來同步對系統資源的訪問,上節中所講述Linux訊號量在核心中也是由等待佇列來實現的。
下面我們重新定義裝置"globalvar",它可以被多個程式開啟,但是每次只有當一個程式寫入了一個資料之後本程式或其它程式才可以讀取該資料,否則一直阻塞。
在Linux驅動程式中,我們可以使用等待佇列(wait queue)來實現阻塞操作。wait queue很早就作為一個基本的功能單位出現在Linux核心裡了,它以佇列為基礎資料結構,與程式排程機制緊密結合,能夠用於實現核心的非同步事件通知機制。等待佇列可以用來同步對系統資源的訪問,上節中所講述Linux訊號量在核心中也是由等待佇列來實現的。
下面我們重新定義裝置"globalvar",它可以被多個程式開啟,但是每次只有當一個程式寫入了一個資料之後本程式或其它程式才可以讀取該資料,否則一直阻塞。
CODE:
#include
#include #include #include #include #include MODULE_LICENSE("GPL"); #define MAJOR_NUM 254 static ssize_t globalvar_read(struct file *, char *, size_t, loff_t*); static ssize_t globalvar_write(struct file *, const char *, size_t, loff_t*); struct file_operations globalvar_fops = { read: globalvar_read, write: globalvar_write, }; static int global_var = 0; static struct semaphore sem; static wait_queue_head_t outq; static int flag = 0; static int __init globalvar_init(void) { int ret; ret = register_chrdev(MAJOR_NUM, "globalvar", &globalvar_fops); if (ret) { printk("globalvar register failure"); } else { printk("globalvar register success"); init_MUTEX(&sem); init_waitqueue_head(&outq); } return ret; } static void __exit globalvar_exit(void) { int ret; ret = unregister_chrdev(MAJOR_NUM, "globalvar"); if (ret) { printk("globalvar unregister failure"); } else { printk("globalvar unregister success"); } } static ssize_t globalvar_read(struct file *filp, char *buf, size_t len, loff_t *off) { //等待資料可獲得 if (wait_event_interruptible(outq, flag != 0)) { return - ERESTARTSYS; } if (down_interruptible(&sem)) { return - ERESTARTSYS; } flag = 0; if (copy_to_user(buf, &global_var, sizeof(int))) { up(&sem); return - EFAULT; } up(&sem); return sizeof(int); } static ssize_t globalvar_write(struct file *filp, const char *buf, size_t len,loff_t *off) { if (down_interruptible(&sem)) { return - ERESTARTSYS; } if (copy_from_user(&global_var, buf, sizeof(int))) { up(&sem); return - EFAULT; } up(&sem); flag = 1; //通知資料可獲得 wake_up_interruptible(&outq); return sizeof(int); } module_init(globalvar_init); module_exit(globalvar_exit); 來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/10617542/viewspace-962133/,如需轉載,請註明出處,否則將追究法律責任。
上一篇:
急救!!!!!!(轉)
請登入後發表評論
登入
全部評論
|
相關文章
- Linux裝置驅動中的阻塞和非阻塞I/OLinux
- 【linux】驅動-13-阻塞與非阻塞Linux
- 深入淺出:Linux裝置驅動中的阻塞和非阻塞I/OLinux
- 蛻變成蝶:Linux裝置驅動中的阻塞和非阻塞I/OLinux
- 驅動Driver-阻塞&非阻塞
- [譯] 非同步程式設計:阻塞與非阻塞非同步程式設計
- 玩轉 PHP 網路程式設計全套阻塞與非阻塞 IOPHP程式設計
- [轉]阻塞/非阻塞與同步/非同步非同步
- 阻塞式程式設計和非阻塞式程式設計區別程式設計
- Socket程式設計中的同步、非同步、阻塞和非阻塞(轉)程式設計非同步
- linux非阻塞式socket程式設計之select()用法Linux程式設計
- 阻塞IO與非阻塞IO
- Linux核心程式設計(阻塞程式)(轉)Linux程式設計
- NIO非阻塞程式設計小案例程式設計
- 同步與非同步 阻塞與非阻塞非同步
- IO multiplexing 與 非阻塞網路程式設計程式設計
- 同步非同步 與 阻塞非阻塞非同步
- 同步、非同步、阻塞與非阻塞非同步
- Linux核心模組程式設計--阻塞程式(轉)Linux程式設計
- 併發程式設計之臨界區\阻塞\非阻塞\死鎖\飢餓\活鎖程式設計
- Java NIO 阻塞式與非阻塞式Java
- Java 網路程式設計 —— 非阻塞式程式設計Java程式設計
- 聊聊執行緒與程式 & 阻塞與非阻塞 & 同步與非同步執行緒非同步
- 同步與非同步、阻塞與非阻塞的理解非同步
- Linux裝置驅動程式 (轉)Linux
- FastAPI之阻塞式io和非阻塞式ioASTAPI
- IO模式設定網路程式設計常見問題總結—IO模式設定,阻塞與非阻塞模式程式設計
- 徹底搞懂同步非同步與阻塞非阻塞非同步
- Linux裝置驅動之字元裝置驅動Linux字元
- 同步非同步,阻塞非阻塞非同步
- 非同步、同步、阻塞、非阻塞非同步
- 同步、非同步、阻塞、非阻塞非同步
- 虛擬裝置驅動程式的設計與實現 (轉)
- Linux 阻塞和非阻塞 IO 實驗學習Linux
- socket阻塞與非阻塞,同步與非同步、I/O模型非同步模型
- 程式與執行緒、同步與非同步、阻塞與非阻塞、併發與並行執行緒非同步並行
- python 網路程式設計----非阻塞或非同步程式設計Python程式設計非同步
- 理解阻塞、非阻塞、同步、非同步非同步