實現非同步通知,核心需要知道幾個東西:哪個檔案
(filp)
,什麼訊號
(sigiio)
,發給哪個程序
(pid)
,收到訊號後做什麼
(sig_handler)
。這些都由前兩個步驟完成了。
在這裡,同樣需要把乙個結構體
struct fasync_struct
新增到核心的非同步佇列頭
(名字是我自己取的
)中。這個結構體用來存放對應裝置檔案的資訊(如
fd, filp)
並交給核心來管理。一但收到訊號,核心就會在這個所謂的非同步佇列頭找到相應的檔案
(fd)
,並在filp->owner
中找到對應的程序
pid,並且呼叫對應的
sig_handler了。
看一下fasync_struct
1097 struct fasync_struct ;
上面紅色標記說所的步驟都是由核心來完成,我們只要做兩件事情:
1)定義結構體
fasync_struct
。struct fasync_struct *async_queue;
2)實現
test_fasync
,把函式
fasync_helper
將fd,filp
和定義的結構體傳給核心。
108 int test_fasync (int fd, struct file *filp, int mode)
109
當裝置可寫時,呼叫函式
kill_fasync
傳送訊號
sigio
給核心。
83 if (dev->async_queue)
講解一下這個函式:
void kill_fasync(struct fasync_struct **fp, int sig, int band)
sig就是我們要傳送的訊號。
band(頻寬)
,一般都是使用
poll_in
,表示裝置可讀,如果裝置可寫,使用
poll_out 4
)當裝置關閉時,需要將
fasync_struct
從非同步佇列中刪除:
117 test_fasync(-1, filp, 0);
刪除也是呼叫
test_fasync
,不過改了一下引數而已。
Linux非同步通知 fasync
要弄明白這個問題,我們得從最基本的原理開始。我們知道,驅動程式執行在核心空間中,應用程式執行在使用者空間中,兩者是不能直接通訊的。但在實際應用中,在裝置已經準備好的時候,我們希望通知使用者程式裝置已經ok,使用者程式可以讀取了,這樣應用程式就不需要一直查詢該裝置的狀態,從而節約資源,這就是非同步通知...
字元裝置驅動之筆記 非同步通知(fasync)
發訊號 1.誰發 2.發給誰 3.發什麼 4.怎麼發 5.收到訊號後做什麼 驅動和應用 發訊號 1.誰發 按鍵中斷服務程式 2.發給誰 使用按鍵的應用程式 3.發什麼 sigio 4.怎麼發 kill fasync 誰,sigio 5.收到訊號後做什麼 sighandler t signal int...
Linux核心的非同步通知
非同步通知類似於中斷,主要用於實現驅動通過傳送訊號通知應用程式。應用層 void my signal fun int signum int main int argc,char argv fcntl fd,f setown,getpid 告訴驅動要發訊號給本應用程式。oflags fcntl fd,...