一 Mutex
互斥對象(mutex)內核對象能夠確保線程擁有對單個資源的互斥訪問權。實際上互斥對象是因此而得名的。互斥對象包含一個使用數量,一個線程ID和一個遞歸計數器。
互斥對象的行爲特性與關鍵代碼段相同,但是互斥對象屬於內核對象,而關鍵代碼段則屬於用戶方式對象。這意味着互斥對象的運行速度比關鍵代碼段要慢。但是這也意味着不同進程中的多個線程能夠訪問單個互斥對象,並且這意味着線程在等待訪問資源時可以設定一個超時值。
ID用於標識系統中的哪個線程當前擁有互斥對象,遞歸計數器用於指明該線程擁有互斥對象的次數。
互斥對象有許多用途,屬於最常用的內核對象之一。通常來說,它們用於保護由多個線程訪問的內存塊。如果多個線程要同時訪問內存塊,內存塊中的數據就可能遭到破壞。互斥對象能夠保證訪問內存塊的任何線程擁有對該內存塊的獨佔訪問權,這樣就能夠保證數據的完整性。
/*****************************************************************************
* OpenST Basic tool library *
* Copyright (C) 2014 Henry.Wen [email protected] . *
* *
* This file is part of OST. *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License version 3 as *
* published by the Free Software Foundation. *
* *
* You should have received a copy of the GNU General Public License *
* along with OST. If not, see <http://www.gnu.org/licenses/>. *
* *
* Unless required by applicable law or agreed to in writing, software *
* distributed under the License is distributed on an "AS IS" BASIS, *
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. *
* See the License for the specific language governing permissions and *
* limitations under the License. *
* *
* Author : Henry.Wen *
* E-Mail : [email protected] *
* License : GNU General Public License (GPL) *
* source code availability:https://github.com/henrywen2011/OST *
* *
*----------------------------------------------------------------------------*
* Remark : Description *
*----------------------------------------------------------------------------*
* Change History : *
* Date | Version | Author | Description *
*----------------------------------------------------------------------------*
* 2014/01/26 | 1.0.0.1 | Henry.Wen | Create file *
*----------------------------------------------------------------------------*
* *
*****************************************************************************/
#ifndef OST_CORE_OSTMUTEX_H
#define OST_CORE_OSTMUTEX_H
#include "OSTTypes.h"
#include "OSTPlatform.h"
#include "OSTBasicable.h"
#if (OST_PLAFORM == OST_PLATFORM_WIN32)
typedef CRITICAL_SECTION OST_MUTEX_SECTION;
#else
#include <pthread>
typedef pthread_mutex_t OST_MUTEX_SECTION;
#endif
OST_NAMESPACE_BEGIN
/**
* @class OSTMutex
* @brief A Mutex (mutual exclusion) is a synchronization mechanism used to control
* access to a shared resourcein a concurrent (multithreaded) scenario.
*/
class OSTMutex : public NonCopyable
{
public:
OSTMutex(void);
~OSTMutex(void);
/**
* @brief Locks the OSTMutex. Blocks if the OSTMutex is held by another thread.
*/
void Lock() const;
/**
* @brief Unlocks the mutex so that it can be acquired by other threads.
*/
void Unlock() const;
/**
* @brief Tries to lock the mutex.
* @return
* -<em>OST_FALSE</em> if the mutex is already held by another thread
* -<em>OST_TRUE</em> otherwise.
*/
OSTBool TryLock();
/**
* @brief Locks the mutex. Blocks up to the given number of milliseconds
* if the mutex is held by another thread.
* Performance Note: On most platforms (including Windows), this member function is
* implemented using a loop calling (the equivalent of) tryLock() and Thread::sleep().
* On POSIX platforms that support pthread_mutex_timedlock(), this is used.
*
* @return
* - <em>OST_TRUE</em> if the mutex was successfully locked.
* - <em>OST_FALSE</em> otherwise.
*/
OSTBool TryLock(long millisecondes);
private:
mutable OST_MUTEX_SECTION m_mutex;
};
/**
* @class AutoLock
* @brief Using the AutoLock class is the preferred way to automatically
* lock and unlock a mutex.
*/
class AutoLock
{
public:
AutoLock(const OSTMutex& mutex, OSTBool autolocked = OST_TRUE) : m_mutex(mutex), m_locked(autolocked)
{
if(autolocked)
{
m_mutex.Lock();
m_locked = autolocked;
}
};
~AutoLock()
{
if(m_locked)
{
m_mutex.Unlock();
}
};
private:
AutoLock(const AutoLock&);
AutoLock& operator = (const AutoLock&);
private:
const OSTMutex& m_mutex;
OSTBool m_locked;
};
/**
* @class AutoUnLock
* @brief Using the AutoUnLock class is the preferred way to automatically
* lock and unlock a mutex.
*/
class AutoUnLock
{
public:
AutoUnLock(const OSTMutex& mutex, OSTBool unlocked = OST_TRUE) : m_mutex(mutex), m_unlocked(unlocked)
{
if(m_unlocked)
{
m_mutex.Unlock();
}
}
~AutoUnLock()
{
m_mutex.Lock();
}
private:
AutoUnLock(const AutoUnLock&);
AutoUnLock& operator = (const AutoUnLock&);
private:
const OSTMutex& m_mutex;
OSTBool m_unlocked;
};
#define LOCK(mutex) AutoLock locker(mutex)
#define UNLOCK(mutex) AutoUnLock locker(mutex)
OST_NAMESPACE_END
#endif//OST_CORE_OSTMUTEX_H
/*****************************************************************************
* OpenST Basic tool library *
* Copyright (C) 2014 Henry.Wen [email protected] . *
* *
* This file is part of OST. *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License version 3 as *
* published by the Free Software Foundation. *
* *
* You should have received a copy of the GNU General Public License *
* along with OST. If not, see <http://www.gnu.org/licenses/>. *
* *
* Unless required by applicable law or agreed to in writing, software *
* distributed under the License is distributed on an "AS IS" BASIS, *
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. *
* See the License for the specific language governing permissions and *
* limitations under the License. *
* *
* Author : Henry.Wen *
* E-Mail : [email protected] *
* License : GNU General Public License (GPL) *
* source code availability:https://github.com/henrywen2011/OST *
* *
*----------------------------------------------------------------------------*
* Remark : Description *
*----------------------------------------------------------------------------*
* Change History : *
* Date | Version | Author | Description *
*----------------------------------------------------------------------------*
* 2014/01/24 | 1.0.0.1 | Henry.Wen | Create file *
*----------------------------------------------------------------------------*
* *
*****************************************************************************/
#include "OSTBaseExc.h"
#include "OSTMutex.h"
OST_NAMESPACE_BEGIN
OSTMutex::OSTMutex(void)
{
pthread_mutexattr_t attr;
if( 0 != pthread_mutexattr_init(&attr) || 0 != pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE))
return;
if (0 != pthread_mutex_init(&m_mutex, &attr))
{
pthread_mutexattr_destroy(&attr);
throw SystemExc("cannot create mutex");
}
pthread_mutexattr_destroy(&attr);
}
OSTMutex::~OSTMutex(void)
{
pthread_mutex_destroy(&m_mutex);
}
void OSTMutex::Lock() const
{
try
{
pthread_mutex_lock(&m_mutex);
}
catch (...)
{
throw SystemExc("Cannot lock mutex");
}
}
void OSTMutex::Unlock() const
{
pthread_mutex_unlock(&m_mutex);
}
OSTBool OSTMutex::TryLock()
{
OSTInt32 rc = pthread_mutex_trylock(&m_mutex);
if (0 == rc)
{
return OST_TRUE;
}
else if (rc == EBUSY)
{
return OST_FALSE;
}
else
{
throw SystemExc("Cannot lock mutex");
}
}
OSTBool OSTMutex::TryLock(long millisecondes)
{
return OST_TRUE;
}
OST_NAMESPACE_END
OSTMutex_Win32.cpp
/*****************************************************************************
* OpenST Basic tool library *
* Copyright (C) 2014 Henry.Wen [email protected] . *
* *
* This file is part of OST. *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License version 3 as *
* published by the Free Software Foundation. *
* *
* You should have received a copy of the GNU General Public License *
* along with OST. If not, see <http://www.gnu.org/licenses/>. *
* *
* Unless required by applicable law or agreed to in writing, software *
* distributed under the License is distributed on an "AS IS" BASIS, *
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. *
* See the License for the specific language governing permissions and *
* limitations under the License. *
* *
* Author : Henry.Wen *
* E-Mail : [email protected] *
* License : GNU General Public License (GPL) *
* source code availability:https://github.com/henrywen2011/OST *
* *
*----------------------------------------------------------------------------*
* Remark : Description *
*----------------------------------------------------------------------------*
* Change History : *
* Date | Version | Author | Description *
*----------------------------------------------------------------------------*
* 2014/01/24 | 1.0.0.1 | Henry.Wen | Create file *
*----------------------------------------------------------------------------*
* *
*****************************************************************************/
#include "OSTBaseExc.h"
#include "OSTMutex.h"
OST_NAMESPACE_BEGIN
OSTMutex::OSTMutex(void)
{
InitializeCriticalSectionAndSpinCount(&m_mutex, 4000);
}
OSTMutex::~OSTMutex(void)
{
DeleteCriticalSection(&m_mutex);
}
void OSTMutex::Lock() const
{
try
{
EnterCriticalSection(&m_mutex);
}
catch (...)
{
throw SystemExc("Cannot lock mutex");
}
}
void OSTMutex::Unlock() const
{
LeaveCriticalSection(&m_mutex);
}
OSTBool OSTMutex::TryLock()
{
try
{
return (TryEnterCriticalSection(&m_mutex) != 0 ? OST_TRUE : OST_FALSE);
}
catch(...)
{
}
throw SystemExc("Cannot lock mutex");
}
OSTBool OSTMutex::TryLock(long millisecondes)
{
return OST_TRUE;
}
OST_NAMESPACE_END