先悔過一下。因為乙個月前就在學習這個,當時解決的差不多了,想著抽個空再記錄這些,沒想到這麼短的時間就已經忘得
差不多了,真是不好,應該趁熱打鐵。廢話不多說了,這裡主要介紹在linux下,利用訊號來實現非同步的串列埠中斷響應。主要思路
很簡單,首先是關聯訊號,在此是關聯處理sigpoll;其次是等待指定的訊號。
非同步i/o的實現有很多方式,中提了幾種,還有較新的epoll,和poll本質上差不多。但本人當時尚不理解這些,沒有明
白select、poll等的具體做法,也採用了多執行緒。其實萬萬不該,由於邏輯處理的不好而導致的程式不可**性太多,因此不太
同意中的觀點,只是用來參考使用了。但我這裡講的做法也是在多執行緒條件下的非同步串列埠通訊。
linux下訊號的概念、原理以及初步的應用中的上、下已經講解得非常到位了,仔細讀讀都能找到自己所需要的。下面
具體記錄我的實現過程。
(1)關聯訊號。
首先是利用sigaction函式來將指定的訊號與處理函式關聯,以及通過fcntl函式確定是在哪個執行緒中,關聯哪個裝置檔案。
那麼先是sigaction函式的原型:int sigaction(int signum,const struct sigaction *act ,struct sigaction *oldact);
其中struct sigaction 中的內容意義可以看,
struct sigaction sact;
sigemptyset(&sact.sa_mask); //一般都先清空關注的訊號集
sact.sa_flags=sa_siginfo; //訊號的附加資訊傳遞開關,可以在訊號sigio上傳遞附加資訊,其實就是
//區別poll_in,poll_out,為什麼要使用附加資訊,自己試試sigio訊號就知道了,它是讀寫不加區分的
sact.sa_sigaction=signal_action; //訊號處理函式,由於利用了訊號附加資訊,函式原型為
//void handler(int signum,siginfo_t *info,void *context);關鍵是siginfo_t結構體中的si_code,其中儲存了poll_in等。
//到時候利用info->si_code== poll_in或poll_out在串列埠有讀或寫時做相應的處理
好了,利用sigaction(sigpoll,&sact,null);完成訊號關聯;再通過下面的操作完成指定的裝置檔案、執行緒
fcntl(fd, f_setown, tid); //tid就是獲取的執行緒號,嵌入式環境下可以使用syscall(sys_gettid);
fcntl(fd, f_setsig,sigpoll ); //關心sigpoll訊號
fcntl(fd,f_setfl,o_async|o_nonblock); //非同步的
(2)等待訊號
其實按照上面的做法,完全可以達到當串列埠有指定資料時進行相應的處理,只要指定的執行緒在,訊號處理函式將會一直起
作用。另一種做法是在接收執行緒等待訊號的發生,而後做相應的處理,自認為雙保險,其實很混亂,只是記下來。注意的是在信
等待訊號傳遞過來的函式sigwaitinfo(),要是想加上時間限制也可以使用sigtimedwait();函式原型:
int sigwaitinfo(const sigset_t *set,siginfo_t *info);按照man中的說法只有當你指定的訊號(在引數set訊號集中)被傳遞到使用這個函式的執行緒時,該函式返回,並將訊號的資訊儲存到後面的info中,也可以供你使用。
(3)嵌入式環境下,在編譯的時候會遇到中的莫名奇妙的問題,其實加上編譯開關選項即可-d_gnu_source,原因麼自己看了。
好了,就這麼多了,其實啥也沒說,只是把一些可能用到的提了下,跟著路線走,應該能找到自己需要的了。寫得太爛了,誰叫給忘得差不多了!@@@
學習參考文獻:
《unix環境高階程式設計》
Linux下的訊號
訊號是作業系統發給程序的一種資訊,程序會針對接收到的資訊做出相應的處理。前面談到乙個概念,叫做訊號量,這裡所說的訊號量和我們今天談到的訊號,除了名字相似,事實上並沒有任何聯絡,是兩個完全不相關的概念,故不可混為一談。訊號是如何產生的呢?先來說說熟悉的場景 使用者輸入命令,在前台啟動乙個程序,然後按下...
Linux下的訊號(二) 阻塞訊號
1,在此之前,必須先了解幾個概念 訊號遞達 delivery 實際執行訊號處理的動作。訊號未決 pending 訊號從產生到遞達之間的狀態。訊號阻塞 block 被阻塞的訊號產生時將保持在未決狀態,直到 程序解除對此訊號的阻塞,才 執行遞達的動作。注意 訊號阻塞和訊號忽略是不同的。只要訊號被阻塞就不...
Linux非同步 訊號量集
在實際的應用中乙個應用程式需要對多個訊號進行處理,為了方便,linux系統引進了訊號集的概念。訊號集用多個訊號組成的資料型別sigset t.可用以下的系統呼叫設定訊號集中所包含的資料。1 sigset t在 include asm generic signal.h中定義。typedef struc...