Windows互斥鎖demo和分析


一:windows創建鎖接口

創建互斥鎖的方法是調用函數CreateMutex

HANDLE CreateMutex(
LPSECURITY_ATTRIBUTESlpMutexAttributes, // 指向安全屬性的指針
BOOLbInitialOwner, // 初始化互斥對象的所有者
LPCTSTRlpName // 指向互斥對象名的指針
);

第一個參數是一個指向SECURITY_ATTRIBUTES結構體的指針,一般的情況下,可以是nullptr。

第二個參數類型為BOOL,表示互斥鎖創建出來后是否被當前線程持有。

第三個參數類型為字符串(const TCHAR*),是這個互斥鎖的名字,如果是nullptr,則互斥鎖是匿名的。

例子:

HANDLE hMutex = CreateMutex(nullptr, FALSE, nullptr);

 

二:windows持有鎖接口:

DWORD WaitForSingleObject(

HANDLE hHandle,
DWORD dwMilliseconds
);

 

這個函數的作用比較多。這里只介紹第一個參數為互斥鎖句柄時的作用。

它的作用是等待,直到一定時間之后,或者,其他線程均不持有hMutex。第二個參數是等待的時間(單位:毫秒),如果該參數為INFINITE,則該函數會一直等待下去。

 

三:釋放鎖

BOOL WINAPI ReleaseMutex(
HANDLE hMutex
);

 四:銷毀

BOOL CloseHandle(
HANDLE hObject
);

下面是網上的一個案例,根據我自己做服務器的需求,模仿者寫了一個:

 

//各種類型的鎖的基類
class BaseLock
{
public:
    BaseLock(){}
    virtual ~BaseLock(){}
    virtual void lock() const = 0 ;
    virtual void unlock() const = 0 ;
};

 

//互斥鎖繼承基類
class Mutex :public BaseLock
{
public:
    Mutex();
    ~Mutex();
    virtual void lock() const;
    virtual void unlock() const;
private:
#if defined _WIN32
    HANDLE m_hMutex;
#endif
};

 

互斥鎖實現文件:

//在構造函數里創建鎖
Mutex::Mutex()
{
    #if defined _WIN32
        m_hMutex = ::CreateMutex(NULL, FALSE, NULL);
    #endif
}

//析構函數里銷毀鎖
Mutex::~ Mutex()
{
    #if defined _WIN32
        ::CloseHandle(m_hMutex);
    #endif
}

//互斥鎖上鎖
void Mutex::lock() const
{
    #if defined _WIN32
      DWORD d = WaitForSingleObject(m_hMutex, INFINITE);
    #endif
}

//互斥鎖解鎖
void Mutex::unlock() const
{
    #if defined _WIN32
      ::ReleaseMutex(m_hMutex);
    #endif
}

 

 

 

class CLock
{
public:
    CLock(const BaseLock & baseLock):m_cBaseLock(baseLock){
        //構造函數里通過基類鎖調用加鎖函數(多態)
        m_cBaseLock.lock();
    }
    ~CLock(){
        //析構函數先解鎖
        m_cBaseLock.unlock();
    }
private:
    //常引用變量,需要在初始化列表初始
    //多態機制
    const BaseLock& m_cBaseLock;
};

 

CLock是留給外界使用的接口類,可以實現自動加鎖和解鎖。構造函數傳入不同類型的鎖,目前只實現了互斥鎖,通過基類類型的引用成員可以實現多態調用不同的lock和

unlock,而CLock析構函數因為會調用基類的unlock,從而實現不同類型的解鎖。

那么讀者可能會有疑問互斥鎖什么時候會銷毀?互斥鎖的銷毀寫在互斥鎖類的析構函數里,

當調用互斥鎖的析構函數就會自動銷毀這把鎖了。什么時候調用互斥鎖的析構函數呢?

之前有介紹過,析構函數的調用順序,先析構子類對象,然后析構子類對象中包含的其他類型的對象,

最后析構基類對象,所以整個流程是 先調用Mutex的構造函數,將Mutex構造的對象傳入CLock的構造函數,

這樣實現自動加鎖,當CLock析構的時候先析構CLock對象,之后析構CLock類里的BaseLock對象,因為是

多態,會自動根據虛析構函數調用子類也就是MutexLock的析構函數,完成銷毀鎖的操作。

 

下面是我服務器中的一段代碼截取,算是這個鎖的示例

void NetWorker::pushNodeInStream(TcpHandler * tcpHandler)
{
        //加鎖處理消息加入到instream里
        CLock mylock(mutexlock);    
        list<MsgNode *> * msgList = tcpHandler->getListMsgs();


}

因為函數}會釋放局部變量,那么就會調用CLock析構函數,接着調用Mutex析構函數。

依次完成解鎖和銷毀鎖的操作。

我的服務器還在制作當中,基本框架制作完畢會做一些服務器設計的研究。

 

謝謝關注我的公眾號:

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM