1 信號基本原理和函數接口
(1)APUE一書中第10章信號
該章節詳細講解了unix系統信號相關的內容,下面這篇文章很好的總結了本章的知識概要,
原文鏈接:http://blog.csdn.net/atfield/article/details/1532506
每小節知識實例參見《APUE》第十章p233~285.
(2)信號的“未決”和“阻塞”
原文鏈接:http://blog.csdn.net/sunyubo458/article/details/4484957
“未決”:信號的狀態,從信號產生到信號被處理的一段時間;
“阻塞”:阻塞的是信號的處理,不阻塞信號的產生。
信號的阻塞和回覆可通過sigprocmask()接口實現。在信號阻塞到回覆的期間,是信號的未決狀態。
信號經過產生--註冊--註銷--處理的四個階段爲信號的生命週期。
實時信號(可靠信號):每產生一個就向task_struct結構中註冊一個sigquene結構體,註銷的時候根據同一信號的註冊個數進行不同處理,釋放sigquene結構體,且(只有一個,則直接在未決信號集中刪除;有多個,則不刪除)。
非實時信號(不可靠信號):每產生一個就向task_struct結構中註冊一個sigquene結構體,註銷的時候根據同一信號的註冊個數進行不同處理,釋放sigquene結構體,在未決信號集中刪除該信號。
2 SIGALRM信號實例----心跳連接
(1)實例背景
在實現心跳連接時,使用的是setitimer()的定時器函數,定時器守護線程每一段時間發送一個SIGALRM信號,主線程收到此信號進行處理,向對方發送一個心跳報文包,感知和對方網絡連接的狀況(網絡線路故障,對方機器宕機等不正常關閉連接的情況)。
(2)關鍵結構TimerManager
對多併發的連接的處理採用的是EPOLL框架,線程間用管道Pipe進行的通信。系統構造一個全局的定時器管理類對象TimerManager(g_TimerManager),擁有pipe(接收各線程的Timer),pipe[0]讀端綁定爲RecvData()-->RecvTimer()的讀端。在init()時,屏蔽SIGALRM信號,創建定時器線程,線程函數用pthread_procmask()恢復信號,設置定時時間(每一秒鐘查詢m_TimerList中的時鐘是否過期)
struct itimerval {
struct timerval it_interval;
struct timerval it_value;
};
struct timeval {
long tv_sec;
long tv_usec;
};
註釋:it_interval爲每經過it_intercal時間久發送一個SIGALRM信號;it_value爲經過該段時間就發送SIGALRM信號(只發一次)。
信號SIGALRM處理函數爲TimerManager.CheckTimeOut()。
需要定時的時候,初始化對象Timer,調用attachTimer()----->registerThread(),將Timer註冊到TimerManager的m_TimerList中,綁定讀端和寫端到全局Epoll中,將Timer對象包裝寫入m_MsgPipe[1]中。
線程函數功能:恢復SIGALRM後,死循環從m_MsgPipe[0]讀取TImer Obj,將Timer Obj insert()進TimerList中,再做checkTimeOut()檢查時鐘超時。
TimerManager維護的成員有:
int m_MsgPipe1[2]; //for TimerManager receiving Timers from main thread
EpollEvent m_EpollEvent; //EpollEvent Handler
std::map<pthread_t,int> m_MsgRPipeList; //綁定的Timer的Epoll的讀端
std::map<pthread_t,int> m_MsgWPipeList; //綁定的Timer的Epoll的寫端
std::multiset<Timer*,LessTimer> m_TimerList; // 管理的多線程多個定時器鏈表
CheckTimeOut():將到時的定時器SendTimer(Timer* P)到TimerManager的m_MsgWPipeList[p->getTid()],觸發主線程Epoll的可讀事件,m_MsgRPipeList[p->getTid()],調用RecvData(),取出Timer *P,調用p->DoAction(),實現定時發送心跳報文包的任務。
註釋:1 文中的TimerManage和Epollr源代碼可Pm我獲得。
2 代碼中設計多重集合的排序,Timer的優先級包裝,與本文探討的定時器信號關係不大,暫不詳解。