互斥锁设计,有效的避免死锁

互斥锁设计,有效的避免死锁

大家好,又见面了,我是全栈君,今天给大家准备了Idea注册码。

下面一段摘自网络,我觉得这是非常好的。锁是理解非常有帮助。
“为什么要加锁?加锁是为了防止不同的线程訪问同一共享资源造成混乱。
打个例如:人是不同的线程,卫生间是共享资源。
你在上洗手间的时候肯定要把门锁上吧。这就是加锁,仅仅要你在里面。这个卫生间就被锁了,仅仅有你出来之后别人才干用。

想象一下假设卫生间的门没有锁会是什么样?

什么是加锁粒度呢?所谓加锁粒度就是你要锁住的范围是多大。

比方你在家上卫生间,你仅仅要锁住卫生间就能够了吧,不须要将整个家都锁起来不让家人进门吧,卫生间就是你的加锁粒度。
如何才算合理的加锁粒度呢?
事实上卫生间并不仅仅是用来上厕所的,还能够洗澡,洗手。这里就涉及到优化加锁粒度的问题。

你在卫生间里洗澡,事实上别人也能够同一时候去里面洗手,仅仅要做到隔离起来就能够。假设马桶,浴缸,洗漱台都是隔开相对独立的,实际上卫生间能够同一时候给三个人使用。当然三个人做的事儿不能一样。这样就细化了加锁粒度,你在洗澡的时候仅仅要关上浴室的门,别人还是能够进去洗手的。

假设当初设计卫生间的时候没有将不同的功能区域划分隔离开。就不能实现卫生间资源的最大化使用。这就是设计架构的重要性。”

从上述知道,有一种情况就是,当你进了卫生间,锁上了门,这时你从窗户逃走了,从而造成卫生间永远被锁住了。

这就是当中一种死锁。
因此能够设想的就是,当我们从卫生间出来的时候(不管正常出来,还是飞出来,…),都能把锁打开。其他人就能进来。

以下的代码就能实现这个功能。
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的生命同期。从而减小锁的粒度。
这个设计不管是原理还是实现,还是蛮简单的。

前提是你有这方面的经验,才会想到这样的实现方法。


一年之后:
时间:20150611
近期想用C++ 11的里面的std::mutex取代原来须要定义各种系统的mutex,由于这样代码更加简洁。
上述设计是之前看LevelDB源代码学来,认为挺好,于是分享出来。而今天改动代码时候发现事实上能够用宏定义。
比如:
#define MUTEX_LOCK()\	m_mutex.lock(); \	{#define MUTEX_UNLOCK()\	}\	m_mutex.unlock();

假设,仅仅使用#define MUTEX_LOCK。没有使用MUTEX_UNLOCK,编译的时候肯定会报错。非常明显,没有MUTEX_UNLOCK。括号是不匹配的。曾经的方法是。假设你忘记了写大括号来控制锁的粒度。那么非常可能要到函数结束的时候才会解锁。如今的方法不存在这样的问题。

可是假设在MUTEX_LOCK 与 MUTEX_UNLOCK之间有return、goto等等待,毫无疑问,将是一个僵局。

版权声明:本文博客原创文章。博客,未经同意,不得转载。

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/117212.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • 网页406错误(网页错误代码1607)

    原因出现网页出现406问一般为一下两种情况 *1、缺失jar包, * *2、如果访问的url的后缀名是以.html结尾的,则服务端不能响应json数据。因为springMVC会误以为.html后缀名的请求,是请求访问某个html文件,则springMVC则无法处理响应json数据 解决方法 *解决方法: * 1、检查所依赖的jar包是否完整 *2、在we…

    2022年4月17日
    59
  • 下载pycharm安装教程_最新安卓开发工具使用方法

    下载pycharm安装教程_最新安卓开发工具使用方法Pycharm可以说是一款进行Python开发功能强大的编辑器。鉴于近期很少有关最新版本的Pycharm安装教程,为了能够帮助刚刚学习Python的朋友们。宋宋老师又给大家准备了一版,会介绍Pycharm的安装和注意事项,希望能够在大家学习Python的道路上起到一点微薄之力。文章分为四部分: Pycharm简介 Pycharm下载 Pycharm安装 Pycharm配置 Pycharm简介PyCharm是由JetBrains打造的一款PythonIDE,J

    2022年8月28日
    7
  • 图卷积网络 GCN Graph Convolutional Network(谱域GCN)的理解和详细推导[通俗易懂]

    图卷积网络 GCN Graph Convolutional Network(谱域GCN)的理解和详细推导[通俗易懂]文章目录1.为什么会出现图卷积神经网络?2.图卷积网络的两种类型2.1vertexdomain(spatialdomain):顶点域(空间域)2.2spectraldomain:频域方法(谱方法)3.什么是拉普拉斯矩阵?3.1常用的几种拉普拉斯矩阵普通形式的拉普拉斯矩阵对称归一化的拉普拉斯矩阵(SymmetricnormalizedLaplacian)随机游走归一化拉普拉斯矩…

    2022年6月11日
    25
  • IDEA安装教程(傻瓜式安装)

    IDEA安装教程(傻瓜式安装)IDEA安装教程1.文件下载1.idea下载2.PJ文件下载2.idea安装步骤3.PJ导包1.文件下载1.idea下载下载地址.版本为2020.1为例2.PJ文件下载下载地址.密码:d79t选择版本进行下载。2.idea安装步骤1.双击打开软件,点击Next2.选择安装目录,然后点击Next(然后会卡一会,取决于电脑性能,在此操作之间,不要着急)3.选择64位,就可以,其他选项看自己需要,然后点击Next4.无需选择,直接点击Install,5.然后点击Finish,完成

    2022年10月2日
    2
  • mac的pycharm安装_mac允许任何安装来源

    mac的pycharm安装_mac允许任何安装来源使用MAC配置Python环境1.打开安装好的Pycharm2.创建一个新项目3.可以添加存放的位置4.选择Python安装路径

    2022年8月28日
    5
  • 【Yolov5】1.认真总结6000字Yolov5保姆级教程[通俗易懂]

    爆肝6000字Yolov5保姆级教程,80岁老奶奶都看得懂。文章特点:一个完整的流程,从头教到尾,不讲冗长的理论,实操

    2022年4月8日
    504

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号