在設備驅動中使用異步通知可使得對設備的訪問可進行時,由驅動主動通知應用程序進行訪問。所以,使用無阻塞I/O的應用程序無需輪詢設備是否可訪問,而阻塞訪問也能夠被相似「中斷」的異步通知所取代。異步通知相似於硬件上的「中斷」概念,比較準確的稱謂是「信號驅動的異步I/O」。css
SIGHUP 終止進程 終端線路掛斷
SIGINT 終止進程 中斷進程
SIGQUIT 創建CORE文件終止進程,而且生成core文件
SIGILL 創建CORE文件 非法指令
SIGTRAP 創建CORE文件 跟蹤自陷
SIGBUS 創建CORE文件 總線錯誤
SIGSEGV 創建CORE文件 段非法錯誤
SIGFPE 創建CORE文件 浮點異常
SIGIOT 創建CORE文件 執行I/O自陷
SIGKILL 終止進程 殺死進程
SIGPIPE 終止進程 向一個沒有讀進程的管道寫數據
SIGALARM 終止進程 計時器到時
SIGTERM 終止進程 軟件終止信號
SIGSTOP 中止進程 非終端來的中止信號
SIGTSTP 中止進程 終端來的中止信號
SIGCONT 忽略信號 繼續執行一箇中止的進程
SIGURG 忽略信號 I/O緊急信號
SIGIO 忽略信號 描述符上能夠進行I/O
SIGCHLD 忽略信號 當子進程中止或退出時通知父進程
SIGTTOU 中止進程 後臺進程寫終端
SIGTTIN 中止進程 後臺進程讀終端
SIGXGPU 終止進程 CPU時限超時
SIGXFSZ 終止進程 文件長度過長
SIGWINCH 忽略信號 窗口大小發生變化
SIGPROF 終止進程 統計分佈圖用計時器到時
SIGUSR1 終止進程 用戶定義信號1
SIGUSR2 終止進程 用戶定義信號2
SIGVTALRM 終止進程 虛擬計時器到時
int sigaction(int signo,const struct sigaction *restrict act, struct sigaction *restrict oact);
//啓動信號機制
void sigterm_handler(int sigo)
{
char data[MAX_LEN];
int len;
len = read(STDIN_FILENO,&data,MAX_LEN);
data[len] = 0;
printf("Input available:%s\n",data);
exit(0);
}
int main(void)
{
int oflags;
//啓動信號驅動機制
signal(SIGIO,sigterm_handler);
fcntl(STDIN_FILENO,F_SETOWN,getpid());
oflags = fcntl(STDIN_FILENO,F_GETFL);
fctcl(STDIN_FILENO,F_SETFL,oflags | FASYNC);
//創建一個死循環,防止程序結束
whlie(1);
return 0;
}
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);
//異步通知的設備結構體模板
struct xxx_dev{
struct cdev cdev;
...
struct fasync_struct *async_queue;//異步結構體指針
};
static int xxx_fasync(int fd,struct file *filp, int mode)
{
struct xxx_dev *dev = filp->private_data;
return fasync_helper(fd, filp, mode, &dev->async_queue);
}
static ssize_t xxx_write(struct file *filp,const char __user *buf,size_t count,loff_t *ppos)
{
struct xxx_dev *dev = filp->private_data;
...
//產生異步讀信息
if(dev->async_queue)
kill_fasync(&dev->async_queue,GIGIO,POLL_IN);
...
}
int xxx_release(struct inode *inode,struct file *filp)
{
//將文件從異步通知列表中刪除
xxx_fasync(-1,filp,0);
...
return 0;
}
同步I/O:linux系統中最經常使用的輸入輸出(I/O)模型是同步I/O,在這個模型中,當請求發出後,應用程序就會阻塞,知道請求知足node
異步I/O:I/O請求可能須要與其它進程產生交疊linux
Linux 系統中最經常使用的輸入/輸出(I/O)模型是同步 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( const 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 );
io_setup( )
//Initializes an asynchronous context for the current process
io_submit( )
//Submits one or more asynchronous I/O operations
io_getevents( )
//Gets the completion status of some outstanding asynchronous I/O operations
io_cancel( )
//Cancels an outstanding I/O operation
io_destroy( )
//Removes an asynchronous context for the current process
經過is_sync_kiocb判斷某kiocb是否爲同步I/O請求api
字符設備:必須明確應支持AIO(極少數是異步I/O操做)緩存
ssize_t (*aio_read) (struct kiocb *iocb, char *buffer, size_t count, loff_t offset);
ssize_t (*aio_write) (struct kiocb *iocb, const char *buffer, size_t count, loff_t offset);
int (*aio_fsync) (struct kiocb *iocb, int datasync);