異步通知是一種通知,相當(dāng)于用于應(yīng)用程序的中斷??捎糜隍?qū)動(dòng)通知進(jìn)程,也可以進(jìn)程通知進(jìn)程。
異步通知接收步驟
默認(rèn)信號(hào)的接收
默認(rèn)的異步IO信號(hào)是SIGIO,使用這個(gè)信號(hào)的接收程序如下:
static void signal_handler(int sig)
{
...
}
...int fd,oflags;
signal(SIGIO,signal_handler); //
fcntl(fd,F_SETOWN,getpid()); //
oflags = fcntl(fd,F_GETFL);
fcntl(fd,F_SETFL,oflags|FASYNC);
...
}
...
signal_handler 是通知要運(yùn)行的函數(shù);
signal(SIGIO,signal_handler); 是注冊(cè)信號(hào)對(duì)應(yīng)的函數(shù)
fcntl(fd,F_SETOWN,getpid()); ? ?這句是設(shè)置異步通知要通知給誰
oflags = fcntl(fd,F_GETFL);
fcntl(fd,F_SETFL,oflags|FASYNC); ?這兩句是使能異步通知。
重點(diǎn)就是使能這部要放在最后。原因如下:如果使能放在前面,異步通知發(fā)生在使能之后,注冊(cè)信號(hào)函數(shù)之前的話。由于找不到注冊(cè)函數(shù),系統(tǒng)會(huì)執(zhí)行默認(rèn)處理函數(shù)。就是會(huì)將進(jìn)程終止。這樣就發(fā)生故障,與預(yù)期不符。
實(shí)時(shí)信號(hào)的接收
實(shí)時(shí)信號(hào)就是更換默認(rèn)信號(hào)SIGIO為實(shí)時(shí)信號(hào)。默認(rèn)信號(hào)SIGIO有些缺點(diǎn),不支持排隊(duì),在信號(hào)處理函數(shù)進(jìn)行過程中如果來了多次SIGIO信號(hào)的話會(huì)被忽略的。實(shí)時(shí)信號(hào)有很多,SIGRTMIN~SIGRTMAX的都是實(shí)時(shí)信號(hào)。
實(shí)時(shí)信號(hào)程序如下:
static void test_handler(int sig, siginfo_t *info, void *context)
...
struct sigaction test;
int flag;fd = open(xxx,xxx);
test.sa_sigaction = test_handler;
test.sa_flags = SA_SIGINFO;
sigemptyset(&test.sa_mask);
sigaction(SIGRTMIN, &test, NULL);
fcntl(fd, F_SETOWN, getpid());
fcntl(fd, F_SETSIG, SIGRTMIN);
oflags = fcntl(fd,F_GETFL);
fcntl(fd,F_SETFL,oflags|FASYNC);
test_handler是通知要運(yùn)行的函數(shù);
sigaction(SIGRTMIN, &test, NULL); ? 是注冊(cè)信號(hào)對(duì)應(yīng)的函數(shù)
fcntl(fd,F_SETOWN,getpid()); ? ?這句是設(shè)置異步通知要通知給誰
fcntl(fd, F_SETSIG, SIGRTMIN); ? 是設(shè)置異步通知使用的信號(hào)是什么
oflags = fcntl(fd,F_GETFL);
fcntl(fd,F_SETFL,oflags|FASYNC); ? 這兩句是使能異步通知。
重點(diǎn)如上,使能放在最后。
異步通知發(fā)送
異步通知發(fā)送分為兩種,進(jìn)程向進(jìn)程發(fā)送和驅(qū)動(dòng)向進(jìn)程發(fā)送。
進(jìn)程向進(jìn)程發(fā)送
這個(gè)比較簡(jiǎn)單,使用kill函數(shù)就可以。
kill的函數(shù)pid是正數(shù)的時(shí)候是目標(biāo)的進(jìn)程,負(fù)數(shù)分幾種情況可以查閱相關(guān)資料。
驅(qū)動(dòng)向進(jìn)程發(fā)送
驅(qū)動(dòng)向進(jìn)程發(fā)送主要分兩步
1 編寫驅(qū)動(dòng)得fasync函數(shù),這個(gè)函數(shù)里要包括fasync_helper,注冊(cè)異步通知
2 在需要發(fā)送異步通知的位置,先判斷異步通知申請(qǐng)成功并可以獲得進(jìn)程號(hào),然后使用kill_fasync發(fā)送通知