結(jié)合阻塞與非阻塞訪問(wèn)、poll函數(shù)可以較好地解決設(shè)備的讀寫,但是如果有了異步通知就更方便了。異步通知的意思是:一旦設(shè)備就緒,則主動(dòng)通知應(yīng)用程序,這樣應(yīng)用程序根本就不需要查詢?cè)O(shè)備狀態(tài),這一點(diǎn)非常類似于硬件上"中斷"地概念,比較準(zhǔn)確的稱謂是"信號(hào)驅(qū)動(dòng)(SIGIO)的異步I/O"。
我們先來(lái)看一個(gè)使用信號(hào)驅(qū)動(dòng)的例子,它通過(guò)signal(SIGIO, input_handler)對(duì)STDIN_FILENO啟動(dòng)信號(hào)機(jī)制,輸入可獲得時(shí)input_handler被調(diào)用,其源代碼如下:
#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;
//啟動(dòng)信號(hào)驅(qū)動(dòng)機(jī)制
signal(SIGIO, input_handler);
fcntl(STDIN_FILENO, F_SETOWN, getpid());
oflags = fcntl(STDIN_FILENO, F_GETFL);
fcntl(STDIN_FILENO, F_SETFL, oflags | FASYNC);
//最后進(jìn)入一個(gè)死循環(huán),程序什么都不干了,只有信號(hào)能激發(fā)input_handler的運(yùn)行
//如果程序中沒(méi)有這個(gè)死循環(huán),會(huì)立即執(zhí)行完畢
while (1);
} |
為了使設(shè)備支持該機(jī)制,我們需要在驅(qū)動(dòng)程序中實(shí)現(xiàn)fasync()函數(shù),并在write()函數(shù)中當(dāng)數(shù)據(jù)被寫入時(shí),調(diào)用kill_fasync()函數(shù)激發(fā)一個(gè)信號(hào),此部分工作留給讀者來(lái)完成。