c++读写锁实现_设计模式PDF

c++读写锁实现_设计模式PDFC++读写锁设计允许读数据同时进行,但与写数据是互斥的存在,只有读数据操作所有完成后释放锁才允许写。反之亦成立。自旋式读写锁,减轻使用者的释放锁的烦恼,当自旋读写锁超出作用域则会自动释放锁。

大家好,又见面了,我是你们的朋友全栈君。如果您正在找激活码,请点击查看最新教程,关注关注公众号 “全栈程序员社区” 获取激活教程,可能之前旧版本教程已经失效.最新Idea2022.1教程亲测有效,一键激活。

Jetbrains全系列IDE使用 1年只要46元 售后保障 童叟无欺


C++ 读写锁设计


本文档为自实现的读写锁,可直接使用


本方案没有用到一切外部库,仅使用到C++11

  • 简析:

   1.本方案是允许读数据同时进行,但与写数据是互斥的存在,只有读数据操作所有完成后释放锁才允许写。反之亦成立。

   2.本方案存在自旋式读写锁,减轻使用者的释放锁的烦恼,当自旋读写锁超出作用域则会自动释放锁。

  • 原理:

  •    读写锁内部存在一个计数器,通过计数器辨别目前有多少同时正在使用读取数据,以及存在一个是否正在写入数据的标识。

  • 代码块

  • RWLock.h


/*
*FileName: RWLock.h
*CreateTime: 2021年11月22日
*Author: yjh
*
*Abbreviation:
*abbr1: RLock		- 读锁
*abbr2: AutoRLock	- 回旋读锁
*abbr3: WLock		- 写锁
*abbr4: AutoWLock	- 回旋写锁
*abbr5: lk			- lock - 锁
*
*Description:
*功能1: 实现读写锁 - 读比较多的情况下节省资源与时间
*功能2: 
*功能3:
*
*/

#pragma once

class CRWLock
{
	friend class CRLock;
	//friend class CAutoRLock;
	friend class CWLock;
	//friend class CAutoWLock;

public:

	CRWLock();

	~CRWLock();

private:

	void ReadLock();
	void ReadUnLock();

	void WriteLock();
	void WriteUnLock();

private:

	//核心 - 读写锁
	std::atomic<uint32_t> m_lkRw;

	//写入中
	std::atomic<bool> m_bWriting;

	//防止m_lk数据异常
	std::mutex m_mt;

};



// ------------------------------ CRLock -----------------------------------
class CRLock
{
public:
	CRLock(CRWLock& rwlk);

	~CRLock();

public:

	void Lock();

	void Unlock();

private:
	CRWLock* m_pRwlk;

};


// ------------------------------ CAutoRLock -----------------------------------
class CAutoRLock
{
public:
	CAutoRLock(CRWLock& rwlk);

	~CAutoRLock();

private:
	CRLock m_rlk;
};


// ------------------------------ CWLock -----------------------------------
class CWLock
{
public:
	CWLock(CRWLock& rwlk);

	~CWLock();

public:

	void Lock();

	void Unlock();
private:
	CRWLock* m_pRwlk;
};


// ------------------------------ CAutoWLock -----------------------------------
class CAutoWLock
{
public:
	CAutoWLock(CRWLock& rwlk);

	~CAutoWLock();

private:
	CWLock m_wlk;
};


  • RWLock.cpp

#include "stdafx.h"

#include <atomic>
#include <mutex>
#include <thread>
#include <chrono>

#include "RWLock.h"


// ------------------------------ CRWLock -----------------------------------
CRWLock::CRWLock() :m_bWriting(false)
{
}


CRWLock::~CRWLock()
{
}

void CRWLock::ReadLock()
{
	m_mt.lock();

	//若此时写锁以上锁 - 等待解锁
	while (m_bWriting)
	    std::this_thread::sleep_for(std::chrono::milliseconds(2));


	m_lkRw++;

	m_mt.unlock();
}
void CRWLock::ReadUnLock()
{
	m_lkRw--;
}

void CRWLock::WriteLock()
{
	m_mt.lock();

	while (m_lkRw)
	    std::this_thread::sleep_for(std::chrono::milliseconds(2));

	m_lkRw++;
	m_bWriting = true;

	m_mt.unlock();
}
void CRWLock::WriteUnLock()
{
	m_lkRw--;

	m_bWriting = false;
}

// ------------------------------ CRLock -----------------------------------
CRLock::CRLock(CRWLock& rwlk)
{
	m_pRwlk = &rwlk;
}

CRLock::~CRLock()
{
}

void CRLock::Lock()
{
	m_pRwlk->ReadLock();
}

void CRLock::Unlock()
{
	m_pRwlk->ReadUnLock();
}

// ------------------------------ CAutoRLock -----------------------------------
CAutoRLock::CAutoRLock(CRWLock& rwlk) :m_rlk(rwlk)
{
	m_rlk.Lock();
}

CAutoRLock::~CAutoRLock()
{
	m_rlk.Unlock();
}

// ------------------------------ CWLock -----------------------------------
CWLock::CWLock(CRWLock& rwlk)
{
	m_pRwlk = &rwlk;
}

CWLock::~CWLock()
{
}


void CWLock::Lock()
{
	m_pRwlk->WriteLock();
}

void CWLock::Unlock()
{
	m_pRwlk->WriteUnLock();
}

// ------------------------------ CAutoWLock -----------------------------------
CAutoWLock::CAutoWLock(CRWLock& rwlk) :m_wlk(rwlk)
{
	m_wlk.Lock();
}

CAutoWLock::~CAutoWLock()
{
	m_wlk.Unlock();
}



  • 使用例子:

CRWLock lk;

void Thread4Read_0()
{
    CAutoRLock rlk(lk);
    
    printf("Thread4Read_0 Running\n");
    
    std::this_thread::sleep_for(std::chrono::milliseconds(1000));
    
    printf("Thread4Read_0 End\n");

}

void Thread4Read_1()
{
    std::this_thread::sleep_for(std::chrono::milliseconds(500));
    CAutoRLock rlk(lk);
     
    printf("Thread4Read_1 Running\n");
    
    std::this_thread::sleep_for(std::chrono::milliseconds(1000));
    
    printf("Thread4Read_1 End\n");

}


void Thread4Write()
{
    std::this_thread::sleep_for(std::chrono::milliseconds(200));
    CAutoWLock wlk(lk);
     
    printf("Thread4Write Running\n");
    
    std::this_thread::sleep_for(std::chrono::milliseconds(100));
    
    printf("Thread4Write End\n");
}


void main()
{
    /*
    *
    *   RunThread是自定义的方法 这里就不实现了,自行使用std::thread启动线程吧
    *
    */

    RunThread(std::bind(Thread4Read_0,this));
    RunThread(std::bind(Thread4Read_0,this));
    RunThread(std::bind(Thread4Read_0,this));
    
    RunThread(std::bind(Thread4Read_1,this));
    
    RunThread(std::bind(Thread4Write,this));
    
    getchar();
    
    return;
}


  • 执行结果:

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

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

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


相关推荐

  • 闫学灿acwing_算法基础课acwing下载

    闫学灿acwing_算法基础课acwing下载给定一个长度为 N 的数列 A,以及 M 条指令,每条指令可能是以下两种之一:C l r d,表示把 A[l],A[l+1],…,A[r] 都加上 d。Q l r,表示询问数列中第 l∼r 个数的和。对于每个询问,输出一个整数表示答案。输入格式第一行两个整数 N,M。第二行 N 个整数 A[i]。接下来 M 行表示 M 条指令,每条指令的格式如题目描述所示。输出格式对于每个询问,输出一个整数表示答案。每个答案占一行。数据范围1≤N,M≤105,|d|≤10000,|A[i]|≤1

    2022年8月9日
    23
  • 【爷青回系列】使用VMware虚拟机安装Windows XP系统!最详细!「建议收藏」

    【爷青回系列】使用VMware虚拟机安装Windows XP系统!最详细!「建议收藏」目录前言一、安装VMware虚拟机二、XP系统镜像下载三、创建WindowsXP虚拟机写在最后前言最近,肯德基的“田园脆鸡堡”回归了,摩尔庄园也正式“开园”了,爷青回!!!终于!终于!小时候左手田园脆鸡堡,右手摩尔庄园的幸福时刻终于要重现了。事先说明,这不是广告植入,也不是今天分享的重点。下面就由我向大家隆重介绍【爷青回系列】使用VMware虚拟机安装WindowsXP系统!操作环境:Windows10一、安装VMware虚拟机【官方下载地址】【免注册下载地址】由于官方下

    2022年8月16日
    5
  • Zigbee协议栈进行数据发送

    Zigbee协议栈进行数据发送Zigbee协议栈进行数据发送是调用AF_DataRequest这个函数,该函数会调用协议栈里面与硬件相关的函数最终将数据通过天线发送出去。  afStatus_tAF_DataRequest(afAddrType_t*dstAddr,//目的地址指针                             endPointDesc_t*srcEP, //发送节点的端点描述符

    2022年5月16日
    34
  • mybatis绑定错误

    mybatis绑定错误

    2022年3月5日
    38
  • 梯度下降算法原理讲解——机器学习「建议收藏」

    梯度下降算法原理讲解——机器学习「建议收藏」详细来讲讲梯度下降算法的原理,感受数学和程序的魅力吧!!

    2022年6月11日
    32
  • Python中优先级_低优先级队列不止5把

    Python中优先级_低优先级队列不止5把优先级队列是一种容器型数据结构,它能管理一队记录,并按照排序字段(例如一个数字类型的权重值)为其排序。由于是排序的,所以在优先级队列中你可以快速获取到最大的和最小的值。你可以认为优先级队列是一种修改过的普通队列:普通队列依据记录插入的时间来获取下一个记录,优先级队列依据优先级来获取下一个记录,而优先级取决于排序字段的值。优先级队列经常用来解决调度问题,比如给更紧急的任务更高的优先级。我们以操作系统…

    2022年9月23日
    4

发表回复

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

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