虽然tc_thread_mutex.h中有#include "util/tc_lock.h", 但也仅仅是为了TC_ThreadMutex_Exception, 可忽略。
看看tc_thread_mutex:
TC_ThreadMutex::TC_ThreadMutex()
{
int rc;
pthread_mutexattr_t attr;
rc = pthread_mutexattr_init(&attr);
assert(rc == 0);
rc = pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_ERRORCHECK);
assert(rc == 0);
rc = pthread_mutex_init(&_mutex, &attr);
assert(rc == 0);
rc = pthread_mutexattr_destroy(&attr);
assert(rc == 0);
if(rc != 0)
{
throw TC_ThreadMutex_Exception("[TC_ThreadMutex::TC_ThreadMutex] pthread_mutexattr_init error", rc);
}
}
TC_ThreadMutex::~TC_ThreadMutex()
{
int rc = 0;
rc = pthread_mutex_destroy(&_mutex);
if(rc != 0)
{
cerr << "[TC_ThreadMutex::~TC_ThreadMutex] pthread_mutex_destroy error:" << string(strerror(rc)) << endl;
}
// assert(rc == 0);
}
void TC_ThreadMutex::lock() const
{
int rc = pthread_mutex_lock(&_mutex);
if(rc != 0)
{
if(rc == EDEADLK)
{
throw TC_ThreadMutex_Exception("[TC_ThreadMutex::lock] pthread_mutex_lock dead lock error", rc);
}
else
{
throw TC_ThreadMutex_Exception("[TC_ThreadMutex::lock] pthread_mutex_lock error", rc);
}
}
}
bool TC_ThreadMutex::tryLock() const
{
int rc = pthread_mutex_trylock(&_mutex);
if(rc != 0 && rc != EBUSY)
{
if(rc == EDEADLK)
{
throw TC_ThreadMutex_Exception("[TC_ThreadMutex::tryLock] pthread_mutex_trylock dead lock error", rc);
}
else
{
throw TC_ThreadMutex_Exception("[TC_ThreadMutex::tryLock] pthread_mutex_trylock error", rc);
}
}
return (rc == 0);
}
void TC_ThreadMutex::unlock() const
{
int rc = pthread_mutex_unlock(&_mutex);
if(rc != 0)
{
throw TC_ThreadMutex_Exception("[TC_ThreadMutex::unlock] pthread_mutex_unlock error", rc);
}
}
int TC_ThreadMutex::count() const
{
return 0;
}
void TC_ThreadMutex::count(int c) const
{
}
这是互斥锁操作的基本封装, 没啥好说的。
看下:
TC_ThreadRecMutex::TC_ThreadRecMutex()
: _count(0)
{
int rc;
pthread_mutexattr_t attr;
rc = pthread_mutexattr_init(&attr);
if(rc != 0)
{
throw TC_ThreadMutex_Exception("[TC_ThreadRecMutex::TC_ThreadRecMutex] pthread_mutexattr_init error", rc);
}
rc = pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE);
if(rc != 0)
{
throw TC_ThreadMutex_Exception("[TC_ThreadRecMutex::TC_ThreadRecMutex] pthread_mutexattr_settype error", rc);
}
rc = pthread_mutex_init(&_mutex, &attr);
if(rc != 0)
{
throw TC_ThreadMutex_Exception("[TC_ThreadRecMutex::TC_ThreadRecMutex] pthread_mutex_init error", rc);
}
rc = pthread_mutexattr_destroy(&attr);
if(rc != 0)
{
throw TC_ThreadMutex_Exception("[TC_ThreadRecMutex::TC_ThreadRecMutex] pthread_mutexattr_destroy error", rc);
}
}
TC_ThreadRecMutex::~TC_ThreadRecMutex()
{
while (_count)
{
unlock();
}
int rc = 0;
rc = pthread_mutex_destroy(&_mutex);
if(rc != 0)
{
cerr << "[TC_ThreadRecMutex::~TC_ThreadRecMutex] pthread_mutex_destroy error:" << string(strerror(rc)) << endl;
}
// assert(rc == 0);
}
int TC_ThreadRecMutex::lock() const
{
int rc = pthread_mutex_lock(&_mutex);
if(rc != 0)
{
throw TC_ThreadMutex_Exception("[TC_ThreadRecMutex::lock] pthread_mutex_lock error", rc);
}
if(++_count > 1)
{
rc = pthread_mutex_unlock(&_mutex);
assert(rc == 0);
}
return rc;
}
int TC_ThreadRecMutex::unlock() const
{
if(--_count == 0)
{
int rc = 0;
rc = pthread_mutex_unlock(&_mutex);
return rc;
}
return 0;
}
bool TC_ThreadRecMutex::tryLock() const
{
int rc = pthread_mutex_trylock(&_mutex);
if(rc != 0 )
{
if(rc != EBUSY)
{
throw TC_ThreadMutex_Exception("[TC_ThreadRecMutex::tryLock] pthread_mutex_trylock error", rc);
}
}
else if(++_count > 1)
{
rc = pthread_mutex_unlock(&_mutex);
if(rc != 0)
{
throw TC_ThreadMutex_Exception("[TC_ThreadRecMutex::tryLock] pthread_mutex_unlock error", rc);
}
}
return (rc == 0);
}
bool TC_ThreadRecMutex::willUnlock() const
{
return _count == 1;
}
int TC_ThreadRecMutex::count() const
{
int c = _count;
_count = 0;
return c;
}
void TC_ThreadRecMutex::count(int c) const
{
_count = c;
}
这里增加了引用计数, 在我看来, 没有太大必要, 这个_count要么为0, 要么为1. 因为如果某线程要做++的操作, 必然是获取了锁, 必然是别的线程释放了锁(_count为0), 此时执行++后, _count才为1.