首页 > 代码库 > 一种有效避免死锁的互斥锁设计
一种有效避免死锁的互斥锁设计
下面是摘自网络的一段话,我觉得很好;对认识锁很有帮助。
“为什么要加锁?加锁是为了防止不同的线程访问同一共享资源造成混乱。
打个比方:人是不同的线程,卫生间是共享资源。
你在上洗手间的时候肯定要把门锁上吧,这就是加锁,只要你在里面,这个卫生间就被锁了,只有你出来之后别人才能用。想象一下如果卫生间的门没有锁会是什么样?
打个比方:人是不同的线程,卫生间是共享资源。
你在上洗手间的时候肯定要把门锁上吧,这就是加锁,只要你在里面,这个卫生间就被锁了,只有你出来之后别人才能用。想象一下如果卫生间的门没有锁会是什么样?
什么是加锁粒度呢?所谓加锁粒度就是你要锁住的范围是多大。
比如你在家上卫生间,你只要锁住卫生间就可以了吧,不需要将整个家都锁起来不让家人进门吧,卫生间就是你的加锁粒度。
怎样才算合理的加锁粒度呢?
其实卫生间并不只是用来上厕所的,还可以洗澡,洗手。这里就涉及到优化加锁粒度的问题。
你在卫生间里洗澡,其实别人也可以同时去里面洗手,只要做到隔离起来就可以,如果马桶,浴缸,洗漱台都是隔开相对独立的,实际上卫生间可以同时给三个人使用,当然三个人做的事儿不能一样。这样就细化了加锁粒度,你在洗澡的时候只要关上浴室的门,别人还是可以进去洗手的。如果当初设计卫生间的时候没有将不同的功能区域划分隔离开,就不能实现卫生间资源的最大化使用。这就是设计架构的重要性。”
比如你在家上卫生间,你只要锁住卫生间就可以了吧,不需要将整个家都锁起来不让家人进门吧,卫生间就是你的加锁粒度。
怎样才算合理的加锁粒度呢?
其实卫生间并不只是用来上厕所的,还可以洗澡,洗手。这里就涉及到优化加锁粒度的问题。
你在卫生间里洗澡,其实别人也可以同时去里面洗手,只要做到隔离起来就可以,如果马桶,浴缸,洗漱台都是隔开相对独立的,实际上卫生间可以同时给三个人使用,当然三个人做的事儿不能一样。这样就细化了加锁粒度,你在洗澡的时候只要关上浴室的门,别人还是可以进去洗手的。如果当初设计卫生间的时候没有将不同的功能区域划分隔离开,就不能实现卫生间资源的最大化使用。这就是设计架构的重要性。”
从上述知道,有一种情况就是,当你进了卫生间,锁上了门,这时你从窗户逃走了,从而造成卫生间永远被锁住了。这就是其中一种死锁。
因此可以设想的就是,当我们从卫生间出来的时候(无论正常出来,还是飞出来,...),都能把锁打开,其它人就能进来。下面的代码就能实现这个功能。
metux.h
这个设计无论是原理还是实现,还是蛮简单的。前提是你有这方面的经验,才会想到这种实现方法。
原文链接:http://www.guimigame.com/thread-685-1-1.html
因此可以设想的就是,当我们从卫生间出来的时候(无论正常出来,还是飞出来,...),都能把锁打开,其它人就能进来。下面的代码就能实现这个功能。
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_Hmutex.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的生命同期,从而减小锁的粒度。
这个设计无论是原理还是实现,还是蛮简单的。前提是你有这方面的经验,才会想到这种实现方法。
原文链接:http://www.guimigame.com/thread-685-1-1.html
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。