在程序开发过程经常使用到多线程,而多线程始终与锁存在紧密地联系,以下详细的介绍如何在C++程序开发过程中自定义锁的几种方法。
1. 下面给出一段代码展现如何通过Mutex实现锁的功能(window platform):
Header File
// // Mutex.h // namespace LockBase { clasee Mutex { public: Mutex(HANDLE mutex); ~Mutex(void); operator bool() const; void Unlock(void); private: HANDLE m_mutex; boll b_unlocked; }; #define lock(hmutex) for(LockBase::Mutex m_lock(hmutex);!m_lock;m_lock.UnLock()) }
Cpp File
// // Mutex.cpp // #include"Mutex.h" using namespace LockBae; Mutex::Mutex(HANDLE mutex):b_unlocked(0) { m_mutex=mutex; ::WaitForSingleObject(m_mutex,INFINE); } Mutex::~Mutex(void) { ::ReleaseMutex(m_nutex); } void Mutex::Unlock(void) { b_unlocked=true; } Mutex::operator bool() const { return b_unlocked; }
Using Demo
// // using lock demo // HANDLE mutex=::CreateMutex(0.false;0); lock(mutex) { }
2.通过CRITICAL_SECTION实现线程锁功能(window platform):
ScopedLock.h File
// // ScopeLock.h // #ifndef ScopedLock_INCLUDED #define ScopedLock_INCLUDED namespace LockBase { template<class T> class scopedLock { // A class that simplifies thread synchronization // with a mutex. // The constructor accepts a Mutex (and optionally // a timeout value in milliseconds) and locks it. // The destructor unlocks the mutex. public: explicit ScopedLock(T& mutex): _mutex(mutex) { _mutex.lock(); } ~ScopedLock() { _mutex.unlock(); } private: T& _mutex; ScopedLock(); ScopedLock(const ScopedLock&); ScopedLock& operator = (const ScopedLock&); }; template<class T> class ScopedLockWithUnlock { // A class that simplifies thread synchronization // with a mutex. // The constructor accepts a Mutex (and optionally // a timeout value in milliseconds) and locks it. // The destructor unlocks the mutex. // The unlock() member function allows for manual // unlocking of the mutex. public: explicit ScopedLockWithUnlock(T& mutex): _pMutex(&mutex) { _pMutex->lock(); } ~ScopedLockWithUnlock() { unlock(); } void unlock() { if (_pMutex) { _pMutex->unlock(); _pMutex = 0; } } private: T* _pMutex; ScopedLockWithUnlock(); ScopedLockWithUnlock(const ScopedLockWithUnlock&); ScopedLockWithUnlock& operator = (const ScopedLockWithUnlock&); }; } //namespace LockBase #endif //ScopedLock_INCLUDED
Mutex_WIN32.h File
// // Mutex_WIN32.h // #ifndef Mutex_WIN32_INCLUDED #define Mutex_WIN32_INCLUDED namespace LockBase { class MutexImpl { protected: MutexImpl(); ~MutexImpl(); void lockImpl(); bool tryLockImpl(); void unlockImpl(); private: CRITICAL_SECTION _cs; }; typedef MutexImpl FastMutexImpl; // // inlines // inline void MutexImpl::lockImpl() { try { EnterCriticalSection(&_cs); } catch (...) { throw std::runtime_error("cannot lock mutex"); } } inline bool MutexImpl::tryLockImpl() { try { return TryEnterCriticalSection(&_cs) != 0; } catch (...) { throw std::runtime_error("cannot lock mutex"); } } inline void MutexImpl::unlockImpl() { LeaveCriticalSection(&_cs); } } //namespace LockBase #endif // Mutex_WIN32_INCLUDED
Mutex_WIN32.cpp File
// // Mutex_WIN32.cpp // namespace LockBase { MutexImpl::MutexImpl() { // the fct has a boolean return value under WInnNt/2000/XP but not on Win98 // the return only checks if the input address of &_cs was valid, so it is safe to omit it InitializeCriticalSectionAndSpinCount(&_cs, 4000); } MutexImpl::~MutexImpl() { DeleteCriticalSection(&_cs); } } // namespace LockBase
Mutex.cpp File
// // Mutex.cpp // #ifdef _MSC_VER #include "Mutex_WIN32.cpp" #else #include "Mutex_LINUX.cpp" #endif using namespace LockBase; Mutex::Mutex() { } Mutex::~Mutex() { }
待续。。。