一: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析構函數。
依次完成解鎖和銷毀鎖的操作。
我的服務器還在制作當中,基本框架制作完畢會做一些服務器設計的研究。
謝謝關注我的公眾號: