C 多线程的互斥锁应用RAII机制
什么是RAII機制
RAII是Resource Acquisition Is Initialization(翻譯成 “資源獲取即初始化”)的簡稱,是C 語言的一種管理資源、避免資源泄漏的慣用法,該方法依賴構造函數資和析構函數的執行機制。
RAII的做法是使用一個類對象,在對象的構造函數中獲取資源,在對象生命期內控制對資源的訪問,最后在對象消失時,其析構函數來釋放獲取的資源;
這里的資源可以是文件句柄,內存,Event,互斥量等等,由于系統的資源是有限的,就好比自然界的石油,鐵礦一樣,不是取之不盡,用之不竭的。所以,我們在編程安全上,要求必須遵循以下幾個步驟:
1. 申請資源
2. 使用資源
3. 釋放資源
在步驟一和步驟二上,我們平時都比較容易把握,而資源的釋放會因為種種編碼原因容易被忽略,導致系統資源實際沒有使用了,但卻沒有釋放或者引發其他問題,影響了系統資源利用率。
沒有使用RAII機制的弊端
那么我們為什么涉及資源管理時,建議使用RAII機制進行編碼呢?
不推薦的編碼方式片段:
while?(TRUE)?{?????//等待直到獲得指定對象的所有權?????EnterCriticalSection(&g_csLock);??????//關鍵代碼段-begin?????if?(g_nIndex ?<?nMaxCnt)?????{?????????cout?<<?"Index?=?"<<?g_nIndex?<<?"?";?????????cout?<<?"Thread2?is?runing"?<<?endl;?????????//權限釋放,容易忘記?????????LeaveCriticalSection(&g_csLock);?????}?????else?????{?????????//權限釋放,容易忘記?????????LeaveCriticalSection(&g_csLock);?????????//關鍵代碼段-end?????????break;?????}??}之所以不推薦這樣的編碼方式是因為EnterCriticalSection/LeaveCriticalSection必須配對使用,很需要依賴人,無法根本上解決問題,如果LeaveCriticalSection函數沒有執行或者忘記添加該API很容易引發問題。
互斥鎖應用RAII機制
為了從根本上解決問題,減少人為因素引發應用系統問題或者資源泄漏,在關鍵代碼段和互斥量這兩種鎖上示范了如何應用RAII機制,簡化多線程互斥編碼。
關鍵代碼段初始化和鎖接口:
class CSLock{public: ? ?CSLock() ? ?{ ? ? ? ?//構造函數時初始化關鍵代碼段對象,獲取資源 ? ? ? ?InitializeCriticalSection(&m_csLock); ? ?}~CSLock() ? ?{ ? ? ? ?//析構函數時釋放為關鍵代碼段對象分配的所有資源,釋放資源 ? ? ? ?DeleteCriticalSection(&m_csLock); ? ?} ?//生命周期內實現對象資源的管理(Lock/Unlock),使用資源 ? ?void Lock() ? ?{ ? ? ? ?EnterCriticalSection(&m_csLock); ? ?}void Unlock() ? ?{ ? ? ? ?LeaveCriticalSection(&m_csLock); ? ?} ? ?//阻止鎖的拷貝和賦值private: ? ?CSLock (const CSLock& ); ? ?CSLock& operator ?= (const CSLock&);private: ? ?CRITICAL_SECTION m_csLock; };創建互斥量對象和鎖接口:
class CMutexLock{public: ? ?CMutexLock() ? ?{ ? ? ? ?m_hMutex = CreateMutex(NULL, FALSE, NULL);//獲取資源 ? ?}~CMutexLock() ? ?{ ? ? ? ?CloseHandle(m_hMutex);//釋放資源 ? ?}void Lock() ? ?{ ? ? ? ?WaitForSingleobject(m_hMutex, INFINITE);//使用資源 ? ?}void Unlock() ? ?{ ? ? ? ?ReleaseMutex(m_hMutex);//使用資源 ? ?} ? ?//阻止鎖的拷貝和賦值private: ? ?CMutexLock(const CMutexLock&); ? ?CMutexLock& operator= (const CMutexLock&);private: ? ?HANDLE ?m_hMutex;};類模板對象,再一次使用RAII機制管理鎖對象的占用和釋放,建議簡化鎖的應用,實現資源的自動回收
template<class T>class CLockGuard{public: ? ?CLockGuard(T& locker) :m_lockerObj(locker) ? ?{ ? ? ? ?m_lockerObj.Lock(); ? ?}~CLockGuard() ? ?{ ? ? ? ?m_lockerObj.Unlock(); ? ?}private:總結
以上是生活随笔為你收集整理的C 多线程的互斥锁应用RAII机制的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 鸭锁骨是什么部位 鸭锁骨属于什么部位的呢
- 下一篇: C 20 协程初探