結合阻塞與非阻塞訪問、poll函數可以較好地解決設備的讀寫,但是如果有了異步通知就更方便了。異步通知的意思是:一旦設備就緒,則主動通知應用程序,這樣應用程序根本就不需要查詢設備狀態,這一點非常類似于硬件上"中斷"地概念,比較準確的稱謂是"信號驅動(SIGIO)的異步I/O"。
我們先來看一個使用信號驅動的例子,它通過signal(SIGIO, input_handler)對STDIN_FILENO啟動信號機制,輸入可獲得時input_handler被調用,其源代碼如下:
#include <sys/types.h>
#include <sys/stat.h>
#include <stdio.h>
#include <fcntl.h>
#include <signal.h>
#include <unistd.h>
#define MAX_LEN 100
void input_handler(int num)
{
char data[MAX_LEN];
int len;
//讀取并輸出STDIN_FILENO上的輸入
len = read(STDIN_FILENO, &data, MAX_LEN);
data[len] = 0;
printf("input available:%s\n", data);
}
main()
{
int oflags;
//啟動信號驅動機制
signal(SIGIO, input_handler);
fcntl(STDIN_FILENO, F_SETOWN, getpid());
oflags = fcntl(STDIN_FILENO, F_GETFL);
fcntl(STDIN_FILENO, F_SETFL, oflags | FASYNC);
//最后進入一個死循環,程序什么都不干了,只有信號能激發input_handler的運行
//如果程序中沒有這個死循環,會立即執行完畢
while (1);
} |
為了使設備支持該機制,我們需要在驅動程序中實現fasync()函數,并在write()函數中當數據被寫入時,調用kill_fasync()函數激發一個信號,此部分工作留給讀者來完成。