c++多線程——鎖技巧
阿新 • • 發佈:2017-08-03
沒有機會 tail 錯誤 特性 每次 中間 urn 你會 get
【轉自】here
編寫程序不容易,編寫多線程的程序更不容易。相信編寫過多線程的程序都應該有這樣的一個痛苦過程,什麽樣的情況呢?朋友們應該看一下代碼就明白了,
void data_process() { EnterCriticalSection(); if(/* error happens */) { LeaveCriticalSection(); return; } if(/* other error happens */) { return; } LeaveCriticalSection(); }
上面的代碼說明了一種情形。這種多線程的互斥情況在代碼編寫過程中是經常遇到的。所以,每次對共享數據進行操作時,都需要對數據進行EnterCriticalSection和LeaveCriticalSection的操作。但是,這中間也不是一帆風順的。很有可能你會遇到各種各樣的錯誤。那麽,這時候你的程序就需要跳出去了。可能一開始遇到error的時候,你還記得需要退出臨界區。但是,如果錯誤多了,你未必記得還有這個操作了。這一錯就完了,別的線程就沒有機會獲取這個鎖了。
那麽,有沒有可能利用C++的特性,自動處理這種情況呢?還真有。我們看看下面這個代碼,
class CLock { CRITICAL_SECTION& cs; public: CLock(CRITICAL_SECTION& lock):cs(lock){ EnterCriticalSection(&cs); } ~CLock() { LeaveCriticalSection(&cs); } } class Process { CRITICAL_SECTION cs; /* other data */ public: Process(){ InitializeCriticalSection(&cs); }~Process() {DeleteCriticalSection(&cs);} void data_process(){ CLock lock(cs); if(/* error happens */){ return; } return; } }
C++的一個重要特點就是,不管函數什麽時候退出,系統都會自動調用類的析構函數。在Process類的data_process函數中,,函數在開始就創建了一個CLock類。那麽,在創建這個類的時候,其實就開始了臨界區的pk。那麽一旦進入到臨界區當中,在error中能不能及時退出臨界區呢?此時,c++析構函數的優勢出現了。因為不管錯誤什麽時候出現,在函數退出之前,系統都會幫我們善後。什麽善後呢?就是系統會調用CLock的析構函數,也就是退出臨界區。這樣,我們的目的就達到了。
其實,這就是一個c++的trick。
c++多線程——鎖技巧