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

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

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

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

異步通知是一種通知,相當(dāng)于用于應(yīng)用程序的中斷??捎糜隍?qū)動通知進(jìn)程,也可以進(jìn)程通知進(jìn)程。

異步通知接收步驟

默認(rèn)信號的接收

默認(rèn)的異步IO信號是SIGIO,使用這個信號的接收程序如下:

...
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); 是注冊信號對應(yīng)的函數(shù)

fcntl(fd,F_SETOWN,getpid()); ? ?這句是設(shè)置異步通知要通知給誰

oflags = fcntl(fd,F_GETFL);

fcntl(fd,F_SETFL,oflags|FASYNC); ?這兩句是使能異步通知。

重點就是使能這部要放在最后。原因如下:如果使能放在前面,異步通知發(fā)生在使能之后,注冊信號函數(shù)之前的話。由于找不到注冊函數(shù),系統(tǒng)會執(zhí)行默認(rèn)處理函數(shù)。就是會將進(jìn)程終止。這樣就發(fā)生故障,與預(yù)期不符。

實時信號的接收

實時信號就是更換默認(rèn)信號SIGIO為實時信號。默認(rèn)信號SIGIO有些缺點,不支持排隊,在信號處理函數(shù)進(jìn)行過程中如果來了多次SIGIO信號的話會被忽略的。實時信號有很多,SIGRTMIN~SIGRTMAX的都是實時信號。

實時信號程序如下:

...
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); ? 是注冊信號對應(yīng)的函數(shù)

fcntl(fd,F_SETOWN,getpid()); ? ?這句是設(shè)置異步通知要通知給誰

fcntl(fd, F_SETSIG, SIGRTMIN); ? 是設(shè)置異步通知使用的信號是什么

oflags = fcntl(fd,F_GETFL);

fcntl(fd,F_SETFL,oflags|FASYNC); ? 這兩句是使能異步通知。

重點如上,使能放在最后。

異步通知發(fā)送

異步通知發(fā)送分為兩種,進(jìn)程向進(jìn)程發(fā)送和驅(qū)動向進(jìn)程發(fā)送。

進(jìn)程向進(jìn)程發(fā)送

這個比較簡單,使用kill函數(shù)就可以。

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

kill的函數(shù)pid是正數(shù)的時候是目標(biāo)的進(jìn)程,負(fù)數(shù)分幾種情況可以查閱相關(guān)資料。

驅(qū)動向進(jìn)程發(fā)送

驅(qū)動向進(jìn)程發(fā)送主要分兩步

1 編寫驅(qū)動得fasync函數(shù),這個函數(shù)里要包括fasync_helper,注冊異步通知

2 在需要發(fā)送異步通知的位置,先判斷異步通知申請成功并可以獲得進(jìn)程號,然后使用kill_fasync發(fā)送通知

相關(guān)推薦

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