Linux裝置驅動中的異步通知與異步I/O
異步通知的意思是:一旦裝置就緒,則主動通知應用程式,這樣應用程式根本就不需要查詢裝置狀态,這一點非常類似于硬體上"中斷"的概念,比較準确的稱謂是"信号驅動的異步I/O"。
Linux信号
Linux系統中,異步通知使用信号來實作。信号也就是一種軟體中斷。
信号的産生:kill raise alarm
使用者按下某些終端鍵;
硬體異常;
終止程序信号;
軟體異常。
信号的處理:
忽略該信号,但SIGSTOP SIGKILL不可忽略;
捕捉該信号,并處理;
執行預設操作。
信号的接收
捕捉信号,安裝信号處理函數:void (*signal(int signum, void(*handler)(int)))(int);
信号函數的原型為:void handler(int signo);
程序執行時,ctrl+c發出SIGINT信号,kill發出SIGTERM信号。
改變程序接收到特定信号後的行為:int sigaction(int signum, const struct sigaction *act,struct sigacton *oldact);
第一個參數可以為除SIGKILL及SIGSTOP外的任何一個特定有效的信号。若第二、三個參數都為NULL,那麼該函數可用于檢查信号的有效性。
在使用者空間處理一個裝置釋放的信号:
通過F_SETOWN IO控制指令設定裝置檔案的擁有者為本程序。
通過F_SETFLIO控制指令設定裝置檔案支援FASYNC。
通過signal()函數連接配接信号和信号處理函數。
信号的釋放
處理FASYNC标志變更的函數。int fasync_helper(int fd, struct file *filp, int mode, struct fasync_struct **fa);
釋放信号用的函數。void kill_fasync(struct fasync_struct **fa, int sig, int band);
AIO概念與GNU C庫函數
AIO基本思想是允許程序發起很多I/O操作,而不用阻塞或等待任何操作完成。
操作:int aio_read(struct aiocb *aiocbp); int aio_write(struct aiocb *aiocbp); int aio_error(struct aiocb *aiocbp); ssize_t aio_return(struct aiocb *aiocbp);
int aio_suspend(struct aiocb *const cblist[], int n, const struct timespec *timeout);
int aio_cancel(int fd, struct aiocb *aiocbp);
int lio_listio(int mode, struct aiocb *list[], int nent, struct sigevent *sig);
使用信号作為AIO的通知
使用回調函數作為AIO的通知
proc檔案系統包含了兩個虛拟的檔案,它們可以用來對異步I/O的性能進行優化。
l /proc/sys/fs/aio-nr檔案提供了系統範圍異步I/O請求的數目。
l /proc/sys/fs/aio-max-nr檔案是所允許的并發請求的最大個數。
AIO與裝置驅動
在核心中每個I/O請求都對應一個kiocb結構體,通過is_sync_kiocb()可以判斷某kiocb是否為為同步I/O請求。
塊裝置和網絡裝置本身是異步的,隻有字元裝置必須明确表明應支援AIO。
操作:ssize_t (*aio_read)(struct kiocb *iocb, char *buff, size_t count, loff_t offset);
ssize_t (*aio_write)(struct kiocb *iocb, const char *buff, size_t count, loff_t offset);
ssize_t (*aio_fsync)(struct kiocb *iocb, int datasync);
AIO不需要改變檔案的位置,是以offset傳遞值而不需要傳遞指針。
aio_read和aio_write()函數本身不一定完成了讀和寫操作,它隻是發起、初始化讀和寫操作。
本文轉自feisky部落格園部落格,原文連結:http://www.cnblogs.com/feisky/archive/2010/06/01/1749345.html,如需轉載請自行聯系原作者