應用場景:
上層業務需調用一個短信中心動態庫,此短信中心模塊單獨開了一個線程,用於從隊列中取出消息來調用相應的短信通信模組,通過無線網絡發送短信內容到用戶手機上。
使用中出現了一個問題,如果底層的短信通信模組動態庫卸載了,在上層業務中測試發送短信,短信中心模塊的線程由於未退出,收到數據后繼續發送,由於底層通信模組被卸載了,就會發送失敗,並導致軟件崩潰。此問題可歸納為一般場景:
動態庫被卸載前,如何正確退出動態庫開的線程。
解決思路:
動態庫A使用兩個事件退出標識,一個是動態庫A退出事件標識EventA,一個是線程B退出事件標識EventB。線程B在一個循環中等待動態庫A的退出事件,收到了上層業務卸載動態庫A調用時,先激活自身退出事件EventA,隨后阻塞等待線程B退出事件。線程B收到EventA后清理資源,並激活線程B的EventB,阻塞等待的動態庫A收到EventB后就知道線程B退出了,之后開始卸載底層通信模組。
相關的代碼片段如下:
聲明兩個 事件內核句柄

初始化:

使用CreateEvent API分配事件內核對象資源,第二個參數為TRUE,表示手動重置事件,第三個參數為FALSE,表示未觸發狀態。多說一句,手動重置事件等待成功不會有副作用(參考 windows核心編程 一書)

當短信中心接到退出指令時,觸發m_hExitEvent事件,然后阻塞等待線程退出事件


新開的線程,在一個循環里等待動態庫退出事件要么每隔1000毫秒從隊列取出數據進行下一步處理,要么立即等到動態庫的退出事件消息,走default流程,觸發線程退出事件。


線程return 0后就正常退出了。
接着動態庫等到線程退出的事件

卸載通信模塊

關閉那兩個事件內核對象,關閉線程句柄


小結一下:
利用兩個退出事件內核對象相互等待的技術,可以保證動態庫模塊和動態庫另開線程依序退出。
