天天看點

Linux裝置驅動中的異步通知與異步I/O

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,如需轉載請自行聯系原作者

繼續閱讀