热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

SharedExclusiveLock共享互斥锁

共享互斥锁,有时也被称为单写多读锁。简单点的应用场景就是:一个写多个读。代码来源是webrtc的SharedExclusiveLock类Thisclassprovides

共享互斥锁,有时也被称为单写多读锁。
简单点的应用场景就是:一个写多个读。

代码来源是webrtc的SharedExclusiveLock类

// This class provides shared-exclusive lock. It can be used in cases like
// multiple-readers/single-writer model.
class SharedExclusiveLock {
public:
SharedExclusiveLock();

// Locking/unlocking methods. It is encouraged to use SharedScope or
// ExclusiveScope for protection.
void LockExclusive();
void UnlockExclusive();
void LockShared();
void UnlockShared();

private:
rtc::CriticalSection cs_exclusive_;
rtc::CriticalSection cs_shared_;
rtc::Event shared_count_is_zero_;
int shared_count_;
};

这个是头文件,下面是cpp:

SharedExclusiveLock::SharedExclusiveLock()
: shared_count_is_zero_(true, true),
shared_count_(0) {
}

void SharedExclusiveLock::LockExclusive() {
cs_exclusive_.Enter();
shared_count_is_zero_.Wait(Event::kForever);
}

void SharedExclusiveLock::UnlockExclusive() {
cs_exclusive_.Leave();
}

void SharedExclusiveLock::LockShared() {
CritScope exclusive_scope(&cs_exclusive_);
CritScope shared_scope(&cs_shared_);
if (++shared_count_ == 1) {
shared_count_is_zero_.Reset();
}
}

void SharedExclusiveLock::UnlockShared() {
CritScope shared_scope(&cs_shared_);
if (--shared_count_ == 0) {
shared_count_is_zero_.Set();
}
}

至于rtc下的CriticalSection和Event,就是将windows下的互斥量和事件简单封装了一下,不贴代码也可以猜到调用了哪些方法。
下面是SharedExclusiveLock的用法:


class SharedScope {
public:
explicit SharedScope(SharedExclusiveLock* lock)
: lock_(lock) {
lock_->LockShared();
}

~SharedScope() { lock_->UnlockShared(); }

private:
SharedExclusiveLock* lock_;
};

class ExclusiveScope {
public:
explicit ExclusiveScope(SharedExclusiveLock* lock)
: lock_(lock) {
lock_->LockExclusive();
}

~ExclusiveScope() { lock_->UnlockExclusive(); }

private:
SharedExclusiveLock* lock_;
};

当时不是调试代码到这的, 而是画类图看到这了,盯了半小时,在记事本上画了一页之后才有个概念:
结合注释知道这是一个单写多读的锁,那么以下几点应该是可预见的:
读时不能写,写时不能读,读读是允许的
反向查了一下代码,发现在webrtc中比较常见的用法如下:

SharedExclusiveLock ss_lock_;

// 001
SharedScope ss(&ss_lock_);
if (ss_) {
ss_->SetMessageQueue(NULL);

// 002
SocketServer* MessageQueue::socketserver() {
SharedScope ss(&ss_lock_);
return ss_;
}

// 003
ExclusiveScope es(&ss_lock_);
ss_ = ss ? ss : own_ss_.get();
ss_->SetMessageQueue(this);

// 004
{
// Wait and multiplex in the meantime
SharedScope ss(&ss_lock_);
if (!ss_->Wait(static_cast<int>(cmsNext), process_io))
return false;
}

看了用法结合源码,分析如下:
SharedExclusiveLock有两互斥两和一个事件,外加一个共享计数
取下名字好接下来分析:互斥量A 互斥两B 事件E
互斥量A主要用于读写之间,互斥量B用于读读之间,且B这样设计是为了保证共享计数的同步
至于E,就是和A配合来保证读写同步

看下源码:
写:
LockExclusive
。。。
UnlockExclusive
过程是获取A,等待E有信号,写操作,释放A
读:
LockShared
。。。
UnlockShared
过程是:等待A,更新共享计数,释放A,读操作
作用域完了之后:更新共享计数

可以看出读和写之间的同步是通过一个互斥量A和一个事件E来保证的

当写时,读是被阻塞的,具体是因为A还被写操作持有,读会阻塞
当读时,写是被阻塞的,具体是因为事件被置为无信号,读会等待
当读时,遇到了另一个读操作,她们俩之间只会将因为共享技术有些竞争,用互斥量B解决之后,就可以读读同时进行了。

好代码一定要细细品味 冷暖自知


推荐阅读
  • centos 7.0 lnmp成功安装过程(很乱)
    下载nginx[rootlocalhostsrc]#wgethttp:nginx.orgdownloadnginx-1.7.9.tar.gz--2015-01-2412:55:2 ... [详细]
  • 本文详细介绍了如何使用Python的多进程技术来高效地分块读取超大文件,并将其输出为多个文件。通过这种方式,可以显著提高读取速度和处理效率。 ... [详细]
  • JUC(三):深入解析AQS
    本文详细介绍了Java并发工具包中的核心类AQS(AbstractQueuedSynchronizer),包括其基本概念、数据结构、源码分析及核心方法的实现。 ... [详细]
  • 本文介绍如何使用OpenCV和线性支持向量机(SVM)模型来开发一个简单的人脸识别系统,特别关注在只有一个用户数据集时的处理方法。 ... [详细]
  • 开机自启动的几种方式
    0x01快速自启动目录快速启动目录自启动方式源于Windows中的一个目录,这个目录一般叫启动或者Startup。位于该目录下的PE文件会在开机后进行自启动 ... [详细]
  • 在HTML布局中,即使将 `top: 0%` 和 `left: 0%` 设置为元素的定位属性,浏览器中仍然会出现空白填充。这个问题通常与默认的浏览器样式、盒模型或父元素的定位方式有关。为了消除这些空白,可以考虑重置浏览器的默认样式,确保父元素的定位方式正确,并检查是否有其他CSS规则影响了元素的位置。 ... [详细]
  • C语言编写线程池的简单实现方法
    2019独角兽企业重金招聘Python工程师标准好文章,一起分享——有时我们会需要大量线程来处理一些相互独立的任务,为了避免频繁的申请释放线程所带 ... [详细]
  • Leetcode学习成长记:天池leetcode基础训练营Task01数组
    前言这是本人第一次参加由Datawhale举办的组队学习活动,这个活动每月一次,之前也一直关注,但未亲身参与过,这次看到活动 ... [详细]
  • 本文将深入探讨 iOS 中的 Grand Central Dispatch (GCD),并介绍如何利用 GCD 进行高效多线程编程。如果你对线程的基本概念还不熟悉,建议先阅读相关基础资料。 ... [详细]
  • 本文介绍了如何将包含复杂对象的字典保存到文件,并从文件中读取这些字典。 ... [详细]
  • 兆芯X86 CPU架构的演进与现状(国产CPU系列)
    本文详细介绍了兆芯X86 CPU架构的发展历程,从公司成立背景到关键技术授权,再到具体芯片架构的演进,全面解析了兆芯在国产CPU领域的贡献与挑战。 ... [详细]
  • 包含phppdoerrorcode的词条 ... [详细]
  • 本文介绍了Spring 2.0引入的TaskExecutor接口及其多种实现,包括同步和异步执行任务的方式。文章详细解释了如何在Spring应用中配置和使用这些线程池实现,以提高应用的性能和可管理性。 ... [详细]
  • 零拷贝技术是提高I/O性能的重要手段,常用于Java NIO、Netty、Kafka等框架中。本文将详细解析零拷贝技术的原理及其应用。 ... [详细]
  • MySQL Decimal 类型的最大值解析及其在数据处理中的应用艺术
    在关系型数据库中,表的设计与SQL语句的编写对性能的影响至关重要,甚至可占到90%以上。本文将重点探讨MySQL中Decimal类型的最大值及其在数据处理中的应用技巧,通过实例分析和优化建议,帮助读者深入理解并掌握这一重要知识点。 ... [详细]
author-avatar
mobiledu2502875993
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有