1. 程式人生 > >多執行緒的那點兒事(之C++鎖)

多執行緒的那點兒事(之C++鎖)

【 宣告:版權所有,歡迎轉載,請勿用於商業用途。  聯絡信箱:feixiaoxing @163.com】

    編寫程式不容易,編寫多執行緒的程式更不容易。相信編寫過多執行緒的程式都應該有這樣的一個痛苦過程,什麼樣的情況呢?朋友們應該看一下程式碼就明白了,

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。