日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

fasync驱动异步通知机制

發布時間:2023/11/30 编程问答 34 豆豆
生活随笔 收集整理的這篇文章主要介紹了 fasync驱动异步通知机制 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

fasync簡介

編輯 異步通知fasync應用于系統調用signal和sigaction函數,簡單的說,signal函數就是讓一個信號與與一個函數對應,每當接收到這個信號就會調用相應的函數。[1] 那么什么是異步通知?異步通知類似于中斷的機制,當設備可寫時,設備驅動函數發送一個信號給內核,告知內核有數據可讀,在條件不滿足之前,并不會造成阻塞。而不像之前學的阻塞型IO和poll,它們是調用函數進去檢查,條件不滿足時還會造成阻塞。

應用層中啟用異步通知機制

編輯 其實在應用層啟用異步通知只三個步驟: 1)signal(SIGIO, sig_handler); 調用signal函數,讓指定的信號SIGIO與處理函數sig_handler對應。 2)fcntl(fd, F_SET_OWNER, getpid()); 指定一個進程作為文件的“屬主(filp->owner)”,這樣內核才知道信號要發給哪個進程。 3)f_flags = fcntl(fd, F_GETFL); fcntl(fd, F_SETFL, f_flags | FASYNC); 在設備文件中添加FASYNC標志,驅動中就會調用將要實現的test_fasync函數。 三個步驟執行后,一旦有信號產生,相應的進程就會收到。

驅動中需要實現的異步通知

編輯

3.1 異步通知內核實現

實現異步通知,內核需要知道幾個東西:哪個文件(filp),什么信號(SIGIIO),發給哪個進程(pid),收到信號后做什么(sig_handler)。這些都由上述前兩個步驟完成了,而這前兩個步驟內核幫忙實現了,所以,我們只需要實現第三個步驟的一個簡單的傳參。

3.2 fasync_struct結構體

要實現傳參,我們需要把一個結構體struct fasync_struct添加到內核的異步隊列中,這個結構體用來存放對應設備文件的信息(如fd, filp)并交給內核來管理。一但收到信號,內核就會在這個所謂的異步隊列頭找到相應的文件(fd),并在filp->owner中找到對應的進程PID,并且調用對應的sig_handler了。 struct fasync_struct { int magic; int fa_fd; struct fasync_struct *fa_next; /* singly linked list */ struct file *fa_file; };

3.3 內核中我們的工作

上面說了前兩個步驟會由內核完成,所以我們只要做兩件事情: 1)定義結構體fasync_struct。 struct fasync_struct *async_queue; 2)實現test_fasync,把函數fasync_helper將fd,filp和定義的結構體傳給內核。 int test_fasync (int fd, struct file *filp, int mode) { struct _test_t *dev = filp->private_data; return fasync_helper(fd, filp, mode, &dev->async_queue); } 函數fasync_helper的定義為: int fasync_helper(int fd, struct file * filp, int on, struct fasync_struct **fapp) 前面的三個參數其實就是teat_fasync的三個參數,所以只要我們定義好的fasync_struct結構體也傳進去就可以了。

3.4 其余的工作

另外還有兩件事: 3)當設備可寫時,調用函數kill_fasync發送信號SIGIO給內核。 if (dev->async_queue){ kill_fasync(&dev->async_queue, SIGIO, POLL_IN); } 講解一下這個函數: void kill_fasync(struct fasync_struct **fp, int sig, int band) sig就是我們要發送的信號。 band(帶寬),一般都是使用POLL_IN,表示設備可讀,如果設備可寫,使用POLL_OUT 4)當設備關閉時,需要將fasync_struct從異步隊列中刪除: test_fasync(-1, filp, 0); 刪除也是調用test_fasync,不過改了一下參數而已。

總結

以上是生活随笔為你收集整理的fasync驱动异步通知机制的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。