加入星計(jì)劃,您可以享受以下權(quán)益:

  • 創(chuàng)作內(nèi)容快速變現(xiàn)
  • 行業(yè)影響力擴(kuò)散
  • 作品版權(quán)保護(hù)
  • 300W+ 專業(yè)用戶
  • 1.5W+ 優(yōu)質(zhì)創(chuàng)作者
  • 5000+ 長期合作伙伴
立即加入
  • 正文
    • 異步通知接收步驟
    • 實(shí)時(shí)信號(hào)的接收
    • 異步通知發(fā)送
    • 驅(qū)動(dòng)向進(jìn)程發(fā)送
  • 相關(guān)推薦
  • 電子產(chǎn)業(yè)圖譜
申請(qǐng)入駐 產(chǎn)業(yè)圖譜

Linux的異步通知接收中要注意使能順序

2023/02/17
1181
閱讀需 6 分鐘
加入交流群
掃碼加入
獲取工程師必備禮包
參與熱點(diǎn)資訊討論

異步通知是一種通知,相當(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;


fd = open(xxx, xxx);

if(fd != -1){
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ù)就可以。

#include <sys/types.h>
#include <signal.h>
int kill(pid_t pid, int sig);

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ā)送通知

相關(guān)推薦

電子產(chǎn)業(yè)圖譜