标签:
想象一下假设卫生间的门没有锁会是什么样?
比方你在家上卫生间,你仅仅要锁住卫生间就能够了吧,不须要将整个家都锁起来不让家人进门吧,卫生间就是你的加锁粒度。
如何才算合理的加锁粒度呢?
事实上卫生间并不仅仅是用来上厕所的,还能够洗澡,洗手。这里就涉及到优化加锁粒度的问题。
你在卫生间里洗澡,事实上别人也能够同一时候去里面洗手,仅仅要做到隔离起来就能够。假设马桶,浴缸,洗漱台都是隔开相对独立的,实际上卫生间能够同一时候给三个人使用。当然三个人做的事儿不能一样。这样就细化了加锁粒度,你在洗澡的时候仅仅要关上浴室的门,别人还是能够进去洗手的。
假设当初设计卫生间的时候没有将不同的功能区域划分隔离开。就不能实现卫生间资源的最大化使用。这就是设计架构的重要性。”
这就是当中一种死锁。
因此能够设想的就是,当我们从卫生间出来的时候(不管正常出来,还是飞出来,...),都能把锁打开。其他人就能进来。
以下的代码就能实现这个功能。
metux.h
#ifndef MUTEX_LOCK_H
#define MUTEX_LOCK_H
#ifndef WIN32
#include <windows.h>
#endif
#ifdef __unix
#include <pthread.h>
#endif // __unix
class Mutex
{
public:
Mutex();
~Mutex();
void Lock();
void Unlock();
private:
Mutex(const Mutex&);
void operator=(const Mutex&);
#ifdef WIN32
CRITICAL_SECTION m_mutex;
#endif // WIN32
#ifdef __unix
pthread_mutex_t m_mutex;
#endif // __unix
};
class MutexLock
{
public:
explicit MutexLock(Mutex *mutex) :m_mutex(mutex)
{
m_mutex->Lock();
};
~MutexLock()
{
m_mutex->Unlock();
};
private:
// 不同意复制
MutexLock(const MutexLock&);
void operator=(const MutexLock&);
Mutex *m_mutex;
};
#endif // !MUTEX_LOCK_H
mutex.cpp#include "mutex.h"
Mutex::Mutex()
{
#ifdef WIN32
InitializeCriticalSection(&m_mutex);
#endif
#ifdef __unix
pthread_mutex_init(&m_mutex, NULL);
#endif // __unix
}
Mutex::~Mutex()
{
#ifdef WIN32
DeleteCriticalSection(&m_mutex);
#endif
#ifdef __unix
pthread_mutex_destroy(&m_mutex);
#endif // __unix
}
void Mutex::Lock()
{
#ifdef WIN32
EnterCriticalSection(&m_mutex);
#endif
#ifdef __unix
pthread_mutex_lock(&m_mutex);
#endif // __unix
}
void Mutex::Unlock()
{
#ifdef WIN32
LeaveCriticalSection(&m_mutex);
#endif
#ifdef __unix
pthread_mutex_unlock(&m_mutex);
#endif // __unix
}
測试Mutex mutex;
void MutexTest()
{
MutexLock l(&mutex);
static int i = 0;
printf("i = %d\n", i);
++i;
}原理就是,当MutexLock生命周期结束时,会调用析构函数,从而能够实现每次从卫生间出来都能够解锁。当然你能够在MutexText加入大括号({})来约束MetexLock的生命同期。从而减小锁的粒度。前提是你有这方面的经验,才会想到这样的实现方法。
#define MUTEX_LOCK() m_mutex.lock(); {
#define MUTEX_UNLOCK() } m_mutex.unlock();假设,仅仅使用#define MUTEX_LOCK。没有使用MUTEX_UNLOCK,编译的时候肯定会报错。非常明显,没有MUTEX_UNLOCK。括号是不匹配的。曾经的方法是。假设你忘记了写大括号来控制锁的粒度。那么非常可能要到函数结束的时候才会解锁。如今的方法不存在这样的问题。版权声明:本文博客原创文章。博客,未经同意,不得转载。
标签:
原文地址:http://www.cnblogs.com/yxwkf/p/4741258.html