1. 程式人生 > >多執行緒中互斥鎖的問題

多執行緒中互斥鎖的問題

最近在多執行緒程式設計中遇到了這樣一個情況,程式中有一些變數是全域性有效的,多個執行緒都要訪問,由於沒有考慮太多,導致執行緒出現一些問題。
於是乎,就想到了互斥鎖,可是遇到了更嚴重的情況:有些執行緒執行一段時間後會被其父執行緒殺掉,假若此時它已對互斥鎖執行了加鎖操作而又未解鎖的話,就造成了死鎖的情況,導致程式頻頻出錯。
這的確是一個令人困惑的問題,如何線上程被殺掉後還能夠將鎖解開著實令我為難了。
還好,執行緒的加鎖、解鎖是通過一個函式來進行的,函式入口處加鎖、出口處解鎖。於是乎,靈光一閃,我何不宣告一個類呢,該類例項在函式入口處宣告對互斥鎖進行加鎖操作,出口處解鎖。
哈,為了確保加鎖、解鎖一定是配對的,我們何不利用一下C++裡面類的建構函式和解構函式呢。如果我不通過new的方式宣告該類例項,而是直接將記憶體分配在棧上,在函數出口處無論如何它都會被析構的。wink_smile.gif


請看:
TLock類標頭檔案:
////////////////////////////////////////////////////////////////////////////////
#ifndef _TLOCK_
#define
_TLOCK_
// 除錯輸出巨集
#define _MY_TEST_
#undef
_MY_TEST_
////////////////////////////////////////////////////////////////////////////////
// 名稱:自動加鎖、解鎖類TLock
// 功能:為多執行緒提供加、解鎖功能
// 用法:不要採用new的方法來宣告例項,否則自動加解鎖功能將失效
////////////////////////////////////////////////////////////////////////////////
#include <iostream.h>
#include
<pthread.h>

#ifdef
DEBUG
    #include "
LOG.hpp"
#endif

static
pthread_mutex_t lockMutex=PTHREAD_MUTEX_INITIALIZER;

class
TLock
{
    private:
        pthread_mutex_t *mylock;

    public:
        TLock(pthread_mutex_t *lock);
        ~TLock();
};

////////////////////////////////////////////////////////////////////////////////
#ifdef DEBUG
extern
LOG log;
extern unsigned long
LOG_DEV;
#endif

////////////////////////////////////////////////////////////////////////////////
#endif
////////////////////////////////////////////////////////////////////////////////

TLock類實現檔案: 

#include "TLock.hpp"

// 在函式中直接宣告TLock類例項,可以確保該函式結束時互斥鎖自動解鎖

// TLock建構函式
TLock::TLock(pthread_mutex_t *lock)
{
    #ifdef

_MY_TEST_
        cout << "begin to lock mutex..." << endl;
    #endif

    #ifdef DEBUG
        log.write(LOG_DEV|TRIVAL|LOG_TIME_TID, "執行緒加鎖操作.../n");
    #endif

    mylock = lock;
    pthread_mutex_lock(mylock); // 加鎖操作
}

// TLock解構函式
TLock::~TLock()
{
    #ifdef _MY_TEST_
        cout << "begin to unlock mutex..." << endl;
    #endif

    #ifdef DEBUG
        log.write(LOG_DEV|TRIVAL|LOG_TIME_TID, "執行緒解鎖操作.../n");
    #endif

    pthread_mutex_unlock(mylock); // 解鎖操作
}

各位看明白了吧,其實是很簡單的。我在需要加解鎖的函式中是這樣加解鎖的:
    int myfunc(int index)
    {
        TLock lock(&lockMutex);
        //...
    }

關鍵在這裡:TLock lock(&lockMutex);
建構函式中將mp(互斥鎖指標)傳進去自動加鎖,然後就不管了,在函式myfunc退出時系統會自動的清除TLock的例項lock,因為它是被宣告在棧上的。而作為一個類,被清除時解構函式一定會及時登場的,於是乎,我們可愛的互斥鎖就不得不被解鎖 ^_^

後話,修改後的加解鎖操作表現的好像還不錯,程式也穩定了不少。如果你也遇到了類似的問題,不妨試一試這個用法。