互斥量 是內核對象,保證線程對共享資源的互斥訪問。與關鍵區 對比:Mutex 可跨進程同步、支援超時等待,但訪問速度較慢(需陷入內核)。本文解析 Mutex 核心結構,並展示一個跨平台(Windows/Linux)的 C++ 封裝庫實現。
典型應用:保護多線程共享內存塊,防止數據競爭導致破損。
核心類 OSTMutex 統一接口,內部使用平台原生同步原語:
CRITICAL_SECTION(用戶態,高性能)+ InitializeCriticalSectionAndSpinCount 優化自旋。pthread_mutex_t 屬性設置為 PTHREAD_MUTEX_RECURSIVE 支援遞歸鎖定。#if (OST_PLATFORM == OST_PLATFORM_WIN32)
typedef CRITICAL_SECTION OST_MUTEX_SECTION;
#else
#include <pthread.h>
typedef pthread_mutex_t OST_MUTEX_SECTION;
#endif
class OSTMutex : public NonCopyable {
public:
OSTMutex(); ~OSTMutex();
void Lock() const; // 阻塞鎖定
void Unlock() const; // 解鎖
OSTBool TryLock(); // 非阻塞嘗試
OSTBool TryLock(long milliseconds); // 超時嘗試
private:
mutable OST_MUTEX_SECTION m_mutex;
};
// RAII 鎖管理器
class AutoLock {
public:
AutoLock(const OSTMutex& m, OSTBool autoLock = OST_TRUE) : m_mutex(m), m_locked(autoLock) {
if (autoLock) m_mutex.Lock();
}
~AutoLock() { if (m_locked) m_mutex.Unlock(); }
private:
const OSTMutex& m_mutex; OSTBool m_locked;
};
#define LOCK(mutex) AutoLock locker(mutex) // 便捷宏
OSTMutex::OSTMutex() { InitializeCriticalSectionAndSpinCount(&m_mutex, 4000); }
OSTMutex::~OSTMutex() { DeleteCriticalSection(&m_mutex); }
void OSTMutex::Lock() const { EnterCriticalSection(&m_mutex); }
void OSTMutex::Unlock() const { LeaveCriticalSection(&m_mutex); }
OSTBool OSTMutex::TryLock() { return TryEnterCriticalSection(&m_mutex) ? OST_TRUE : OST_FALSE; }
OSTBool OSTMutex::TryLock(long ms) { return OST_TRUE; /* 簡化實現 */ }
OSTMutex::OSTMutex() {
pthread_mutexattr_t attr;
pthread_mutexattr_init(&attr);
pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE);
pthread_mutex_init(&m_mutex, &attr);
pthread_mutexattr_destroy(&attr);
}
OSTMutex::~OSTMutex() { pthread_mutex_destroy(&m_mutex); }
void OSTMutex::Lock() const { pthread_mutex_lock(&m_mutex); }
void OSTMutex::Unlock() const { pthread_mutex_unlock(&m_mutex); }
OSTBool OSTMutex::TryLock() {
int rc = pthread_mutex_trylock(&m_mutex);
return (rc == 0) ? OST_TRUE : (rc == EBUSY ? OST_FALSE : throw SystemExc("Cannot lock"));
}
AutoLock 確保異常安全,離開作用域自動解鎖。NonCopyable 禁止拷貝構造/賦值,避免鎖對象複製導致未定義行為。pthread_mutex_timedlock,Windows 需循環 TryLock+Sleep 實現。