多线程:多读少写锁(Readers–writer lock)
先来几个同义词
- readers–writer (RW) lock
- shared - exclusive lock
- multiple readers/single-writer lock
- multi-reader lock
- push lock
解决的问题
- 允许多个线程同时读取数据。只允许一个线程写或更新数据
- 写数据时,其他的写操作和读操作要被阻塞。(SQLite 的 WAL 不是,允许同时读写)
实现时需要考虑的问题
读优先还是写优先?
读优先的概述如下:
尽量满足并发的读操作,当已经有线程在读数据的时候,其他读线程无需等待,而写线程需要等待所有正在进行的读操作之后才能执行
写优先的概述如下:
尽量满足写操作,尽管写操作不能并发,但是可以排队,优先于等待的读线程获得执行权
对系统刷新要求的高标准系统,应该使用写优先的锁,比如路由器、证券交易平台。通常用很多读请求,如果等所有读请求都结束,可能更新信息已经来不及了,即发生 starvation 问题。
解决问题的思路
Readers–writer locks are usually constructed on top of mutexes and condition variables, or on top of semaphores.
- 互斥量+条件变量
- 信号量
具体实现参见参考资料。
默认实现都是读优先的锁。如果要实现写优先的锁,可以通过加标记位判断是否有写请求在等待。
读写锁重入问题及死锁
通常reader lock是可重入的,writer lock是不可重入的。但是为了防止writer饥饿,writer lock通常会阻塞后来的reader lock,因此reader lock在重入的时候可能死锁。
即获取读锁,尝试获取写锁(为了防止饥饿,不允许再次获取读锁),进行重入,即尝试获取读锁。
bingo,发生死锁啦
参考
- Readers–writer lock
- Starvation (computer science)
- 读写锁的几种实现方式-互斥量,信号量,条件变量
- 用信号量和读写锁解决读者写者问题
- Linux下写者优先的读写锁的设计
- 读写锁的性能问题及替代方案
多线程:多读少写锁(Readers–writer lock)的更多相关文章
- java多线程 -- ReadWriteLock 读写锁
写一条线程,读多条线程能够提升效率. 写写/读写 需要“互斥”;读读 不需要互斥. ReadWriteLock 维护了一对相关的锁,一个用于只读操作,另一个用于写入操作.只要没有 writer,读取锁 ...
- Java多线程之读写锁机制
Java多线程中有很多的锁机制,他们都有各自的应用场景,例如今天我说的这种锁机制:读写锁 读写锁,见名知意,主要可以进行两种操作,读和写操作,他们之间结合使用起来又是各不相同的.比如多个线程之间可以同 ...
- 技术笔记:Delphi多线程应用读写锁
在多线程应用中锁是一个很简单又很复杂的技术,之所以要用到锁是因为在多进程/线程环境下,一段代码可能会被同时访问到,如果这段代码涉及到了共享资源(数据)就需要保证数据的正确性.也就是所谓的线程安全.之前 ...
- java 多线程 day12 读写锁
import java.util.Random;import java.util.concurrent.locks.ReadWriteLock;import java.util.concurrent. ...
- 多线程程序设计学习(7)read-write lock pattern
Read-Write Lock Pattern[读写]一:Read-Write Lock Pattern的参与者--->读写锁--->数据(共享资源)--->读线程--->写线 ...
- 多线程同步与并发访问共享资源工具—Lock、Monitor、Mutex、Semaphore
“线程同步”的含义 当一个进程启动了多个线程时,如果需要控制这些线程的推进顺序(比如A线程必须等待B和C线程执行完毕之后才能继续执行),则称这些线程需要进行“线程同步(thread synchro ...
- Android多线程研究(9)——线程锁Lock
在前面我们在解决线程同步问题的时候使用了synchronized关键字,今天我们来看看Java 5.0以后提供的线程锁Lock. Lock接口的实现类提供了比使用synchronized关键字更加灵活 ...
- Java多线程之线程同步【synchronized、Lock、volatitle】
线程同步 线程同步:当有一个线程在对内存进行操作时,其他线程都不可以对这个内存地址进行操作,直到该线程完成操作, 其他线程才能对该内存地址进行操作,而其他线程又处于等待状态,实现线程同步的方法有很多. ...
- 上传程序Dictionary 字典 哈希--多读一写锁ReaderWriterLock
//上传程序Dictionary 字典 哈希 /// <summary> /// 车辆控制信息哈斯表,Key是终端号,Value是车辆信息控制对象 /// </summary> ...
随机推荐
- stl string 小练习
最近没啥可写的 这里写下做的STL小练习 作为记录 去除指定字符串中的空格 获取文件名并根据名字创建临时文件,以TMP后缀结尾,已经为TMP后缀结尾文件则创建以XXX后缀结尾文件 读取一行输入内容 ...
- 2014.1.4 cxf spring webservice
先创建 webservice 服务端 . 首先下载 cxf jar 包 , cxf-2.7.8 . 新建 web 项目 aa . 将下载的cxf 压缩文件解压,将lib 下的jar 全部build p ...
- SpringBoot集成篇(二) 异步调用Async
什么是异步调用? 异步调用是相对于同步调用而言的,同步调用是指程序按预定顺序一步步执行,每一步必须等到上一步执行完后才能执行,异步调用则无需等待上一步程序执行完即可执行. 如何实现异步调用? 多线程, ...
- Exce行列变色
- C#基础:在using中创建对象
在using中创建的对象的类必须是实现了IDispose接口的类,示例代码如下: static void Main(string[] args) { Method(); Console.WriteLi ...
- Javascript 中函数的 length 属性
每个函数都有一个 length属性 (函数名.length), 表示期望接收的函数的个数(而不是实际接收的参数个数) 它与arguments不同. arguments.length 是表示函数实际接收 ...
- OpenGL ES之GLFW窗口搭建
概述 本章节主要总结如何使用GLFW来创建Opengl窗口.主要包括如下内容: OpenGl窗口创建介绍 GLFW Window版编译介绍 GLFW简单工程源码介绍 OpenGL窗口创建介绍 能用于O ...
- [翻译Joel On Software]选择一门语言/Choosing a language
Joel on Software Choosing a language 选择一门语言 by Joel Spolsky Sunday, May 05,2002 Why do developerscho ...
- WinRT 中后台任务类的声明
要实现后台任务,需要实现IBackgroundTask接口 public sealed class SimpleTask : IBackgroundTask { public void Run(IBa ...
- KVM NAT网络模式配置
NAT方式原理 NAT方式是kvm安装后的默认方式.它支持主机与虚拟机的互访,同时也支持虚拟机访问互联网,但不支持外界访问虚拟机. 检查当前的网络设置: #virsh net-list --all N ...