在很多應用中都需要應用程式主動去查詢驅動中是否有資料可讀或者是否可以向驅動寫入資料,對於單執行緒的應用,這可能會導致程序阻塞。當然,可以使用select來不斷輪詢驅動是否可讀或可寫,但是這並不是很好的解決方法,更好的解決方式是由驅動主動通知應用程式其狀態,而不是應用程式主動去查詢驅動的狀態。
非同步通知就類似於**,應用程式首先向驅動註冊乙個**函式,然後應用程式就可以無阻塞地去做其他事情,當驅動認為其已經可以被寫入或者被讀取時就會呼叫應用程式之前註冊的**函式,從而實現非同步通知。下面以乙個簡單的例子說明驅動中非同步通知的用法。
新建eclipse工程,具體過程見前面的文章,編寫非同步通知驅動程式,為了方便說明,這裡使用核心定時器的超時操作作為觸發非同步通知的行為(實際使用中應根據具體的時機來觸發),驅動程式比較簡單,直接上**:
1 #include 2 #include 3 #include 4 #include 5 #include 6 #include 7 #include 8 #include 9 #include 10 #include 11 #include 12 #include 13 #include 14 #include string.h>編譯成功後會生成fasync.ko檔案,先載入該驅動:15 #include 16 #include 17 #include 18 #include //
for sigio,poll_in
19 #include 20 #include 21
22//
裝置名23
#define device_name "sync"
24//
主裝置號
25#define device_major 228
2627
//非同步通知結構變數
28struct fasync_struct *async_queue;
29//
核心定時器
30struct
timer_list my_timer;
3132
33//
定時器超時函式
34static
void timer_function(unsigned long
arg)
3539
40//
使用者空間呼叫fcntl函式時會呼叫這個函式
41static
int async_fasync(int fd, struct file *filp, int
mode)
4246
47static
int async_open(struct inode *node,struct file *flip)
4861
6263
static
struct file_operations async_fops =64;
6970
71static
int __init dev_init(void)72
82else
838788}
8990
91static
void __exit dev_exit(void)92
9798
99module_init(dev_init);
100module_exit(dev_exit);
101 module_license("
gpl"
);102 module_author("
lkn@scut
");
#insmod fasync.ko
然後,在/dev目錄下建立裝置檔案:
#mknod sync c 228 1
接著,編寫應用程式:
1 #include 2 #include 3 #include 4 #include 5 #include 6 #include 7 #include 89編譯之://是否已接收到訊號標誌
10int flag = 0;11
12//
訊號處理函式定義,由核心呼叫執行
13void sig_handler(int
signo)
14
20}
2122
intmain()
2340
41//
告訴驅動當前程序的pid
42fcntl(async_fd, f_setown, getpid());
43//
設定驅動的fasync屬性,支援非同步通知
44 fcntl(async_fd, f_setfl, fcntl(async_fd, f_getfl) |fasync);
4546 printf("
waiting for receive...\n");
4748
while(!flag)
49
5152
close(async_fd);
5354
return
0;
55 }
gcc -o fasync_test fasync_test.c
執行應用程式,效果如圖:
linux中驅動非同步通知
驅動程式執行在核心空間中,應用程式執行在使用者空間中,兩者是不能直接通訊的。但在實際應用中,在裝置已經準備好的時候,我們希望通知使用者程式裝置已經ok,使用者程式可以讀取了,這樣應用程式就不需要一直查詢該裝置的狀態,從而節約了資源,這就是非同步通知。好,那下乙個問題就來了,這個過程如何實現呢?簡單,...
linux裝置驅動中的非同步通知機制
非同步通知的意思是 一旦裝置就緒,則主動通知應用程式,這樣應用程式根本就不需要查詢裝置狀態,這一點非常類似於硬體上 中斷 的概念,比較準確的稱謂是 訊號驅動的非同步i o 訊號是在軟體層次上對中斷機制的一種模擬,在原理上,乙個程序收到乙個訊號與處理器收到乙個中斷請求可以說是一樣的.訊號是非同步的,乙...
Linux裝置驅動中的非同步通知和非同步IO
前面兩章分別提到io模型中的阻塞與非阻塞linux驅動 六 裝置驅動中的阻塞與非阻塞io,io多路復用驅動中輪詢操作實現,這一章我們再來看看非同步io,這樣,io模型就可以都搞定了。回顧一下在應用程式中使用非同步io的步驟 1,應用程式 1 設定非同步標誌位 int flags fcntl fd,f...