目錄
前言
14. 異步通知
14.1 異步通知的一些概念
14.2 Linux 信号
14.3 信号接收
14.4 使用流程
14.4.1 參考流程圖
14.4.2 分析&程式設計步驟
14.4.3 使用函數說明
14.4.3.1 相關結構體及參考模型
14.4.3.2 signal 函數
14.4.3.3 kill_fasync 函數
本章内容為驅動基石之一。
驅動隻提供功能,不提供政策。
阻塞與非阻塞是 APP 詢問 驅動裝置。
異步通知是 驅動裝置 主動通知 APP。
原文:https://www.cnblogs.com/lizhuming/p/14918049.html
異步通知:一旦裝置就緒,則主動通知APP,這樣APP就不用輪詢查詢裝置狀态了。
異步IO:APP 發起 IO 請求後,立即傳回。然後再查詢 IO 完成情況,或者 IO 完成後被調回。這個過程叫做 異步IO。
可以使用 信号 來進行程序間通信(IPC)。
Linux信号表:
路徑參考:include\uapi\asm-generic\signal.h
信号
值
說明
SIGHUP
1
挂起
SIGINT
2
中斷中斷
SIGQUIT
3
終端退出
SIGILL
4
無效指令
SIGTRAP
5
跟蹤陷阱
SIGABRT
6
異常終止信号,和 SIGIOT 同義
SIGIOT
IOT陷阱,和 SIGABRT 同義
SIGBUS
7
BUS錯誤
SIGFPE
8
浮點異常
SIGKILL
9
強制終止
SIGUSR1
10
使用者自定義信号1
SIGSEGV
11
無效的記憶體段處理
SIGUSR2
12
使用者自定義信号2
SIGPIPE
13
半關閉管道的寫操作
SIGALRM
14
計時器到期
SIGTERM
15
終止
SIGSTKFLT
16
堆棧錯誤
SIGCHLD
17
子程序已經停止或退出
SIGCONT
18
如果停止了,繼續執行
SIGSTOP
19
停止執行
SIGTSTP
20
終端停止信号
SIGTTIN
21
背景程序需要從終端讀取輸入
SIGTTOU
22
背景程序需要從終端寫出
SIGURG
23
緊急的套接字事件
SIGXCPU
24
超額使用CPU配置設定的時間
SIGXFSZ
25
檔案尺寸超額
SIGVTALRM
26
虛拟時鐘信号
SIGPROF
27
時鐘信号描述
SIGWINCH
28
出口尺寸變化
SIGIO
29
I/O
SIGPOLL
除了 SIGSTOP 和 SIGKILL 兩個信号外,程序能夠忽略或捕獲其它所有信号。
一個信号被捕獲的意思是當一個信号到達時有相應代碼處理它。
如果一個信号沒有被這程序所捕獲,核心将采取預設行為處理。
流程圖參考韋東山:

分析中的細節部分會在後本節後面說明
分析:
②:綁定信号與回調函數。使用<code>sighandler_t signal(int signum, sighandler_t handler)</code> 。
③:把 APP PID 告訴核心。同時,該 PID 會儲存到該驅動的核心檔案 file 結構體中。
④:讀取該驅動程式檔案的 Flag。
⑤:設定 Flag 裡面的 FASYNC 位為 1。當 FASYNC 位發生變化時,該驅動會調用驅動操作 <code>drv_fasync</code> 函數。
⑥:驅動開發者實作的函數。主要是調用 fasync_helper 函數。
⑦:調用 fasync_helper() 函數,主要是把 驅動程式核心檔案 file 結構體綁定到 button_async->fa_file 中。而 file 包含了 APP 的 PID。是以發送信号時,隻需要使用 button_async 作為參數即可。
⑩:發送信号給對應的 APP。參數為 button_async。
注:button_async 結構體由驅動開發者建立,維護。
APP 信号程式設計步驟:
①:編寫信号回調函數。
②:綁定信号與回調函數。
③:打開驅動。
④:擷取 PID ,告知核心。
⑤:擷取程序狀态值。
⑥:目前狀态值添加異步功能,觸發調用驅動異步處理函數。
KERNEL 信号程式設計步驟:
①:定義異步結構體。
②:實作異步操作函數,并把該函數填充到裝置核心驅動操作結構體中。
該函數内容主要調用 fasync_helper() 函數,初始化異步結構體。(把 file ,核心PID,交給異步結構體)
③:發送信号。
APP 模型 截段:
fasync_struct:
(在核心源碼中,目前沒有去找核心文檔該結構體内容的相關資訊)
APP 使用。
函數原型:<code>sighandler_t signal(int signum, sighandler_t handler)</code> :
功能:綁定信号與回調函數。
signum:信号類型。除 SIGKILL 和 SIGSTOP 外的任何一種信号。
handler:該參數有三種類型。
①:SIG_IGN 類型。表示忽略該信号。
②:SIG_DFL 類型。表示恢複對信号的系統預設處理。
③:sighandler_t 類型的函數指針。即是回調函數。<code>typedef void (*sighandler_t)(int);</code> 。
注:APP 收到信号執行回調函數時,signum 參數會被傳到回調函數的形參傳遞給回調函數。即是回調函數的形參就是信号類型。
KERNEL 使用。
函數原型:<code>void kill_fasync(struct fasync_struct **fp, int sig, int band)</code> :
功能:發送信号給 fp 參數綁定的程序。(by PID)
參考路徑:linux-5.12.8\fs\fcntl.c
fp:需要操作的 fasync_struct。
sig:信号類型。
band:可讀時設定為 POLL_IN;可寫時設定為 POLL_OUT。當然該參數還可以填
POLL_MSG。以上三個值在應用層接收時,si_code 分别為 0x01、0x02、0x03。