一 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