golang中的读写锁
简介
互斥锁本质是当一个协程访问的时候,其他协程都不能访问.
其实主要是想:修改数据要同步,这样其他协程才可以感知到,所以真正的互斥应该是读取和修改,修改和修改之间,读和读是没有互斥操作的必要的
读写锁可以让多个读并发,但是对于写是互斥的.
当一个协程在写的时候,其他协程不能读也不能写
同时只能存在写锁定或读锁定(读和写互斥)
go中的读写锁由结构类型sync.RWMutex
表示.这个类型的方法集合中包含两对方法
一组是对写操作的锁定和解锁,简称:写锁定和写解锁
func (*RWMutex) Lock()
func (*RWMutex) UnLock()
另一组表示对读操作的锁定和解锁,简称为读锁定和读解锁
func (*RWMutex) RLock()
func (*RWMutex) RUlock()
读时共享,写时独占.
写优先级比读高
读锁也算个锁,锁只能有一把
package mainimport ("fmt""sync"
)func main() {var mutex sync.Mutexfmt.Printf("%+v\n", mutex)mutex.Lock()fmt.Printf("%+v\n", mutex)mutex.Unlock()fmt.Printf("%+v\n", mutex)
}
输出
{state:0 sema:0}
{state:1 sema:0}
{state:0 sema:0}
可以看出当Lock()时,state为1,Unlock()时,state为0。
使用
读写锁,最好不要和channel一起使用会造成死锁
//创建读写锁
var mx sync.RWMutex//读
func readGo(in <-chan int, idx int) {for {//mx.RLock() //读锁//要求写端同时在线,自己阻塞num := <-infmt.Println("读取: ", num, idx)time.Sleep(time.Millisecond * 300) //放大实验现象//mx.RUnlock()}}//写
func writeGo(out chan<- int, idx int) {for {//生成随机数num := rand.Intn(1000)mx.Lock() //写锁out <- numfmt.Println("------写入: ", num, idx)time.Sleep(time.Millisecond * 30) //放大实验现象mx.Unlock()}
}func main() {//播种随机数rand.Seed(time.Now().UnixNano())ch := make(chan int) //数据传递的channelfor i := 0; i < 5; i++ {go writeGo(ch, i+1)}for i := 0; i < 5; i++ {go readGo(ch, i+1)}for {;}}
全局变量数据同步
//创建读写锁
var mx sync.RWMutex
var i int //全局变量模拟共享数据//读
func readGo(idx int) {for {mx.RLock() //读锁num := ifmt.Println("读取: ", num, idx)//time.Sleep(time.Millisecond * 30) //放大实验现象mx.RUnlock()}}//写
func writeGo(idx int) {for {mx.Lock() //写锁//生成随机数num := rand.Intn(1000)i = numfmt.Println("------写入: ", num, idx)time.Sleep(time.Millisecond * 30) //放大实验现象mx.Unlock()}
}func main() {//播种随机数rand.Seed(time.Now().UnixNano())for i := 0; i < 5; i++ { //5个读过程go readGo(i+1)}for i := 0; i < 5; i++ { //5个写过程go writeGo(i+1)}for {;}
}
golang中的读写锁相关推荐
- golang中关于读写锁、互斥锁的理解
锁的概述 为了解决协程同步的问题我们使用了channel,但是GO也提供了传统的同步工具. 它们都在GO的标准库代码包sync和sync/atomic中. 下面我们看一下锁的应用. 什么是锁呢?就是某 ...
- MongoDB中的读写锁
1. MongoDB 使用的锁 MongoDB 使用的是"readers-writer"锁, 可以支持并发但有很大的局限性 当一个读锁存在,许多读操作可以使用这把锁,然而, 当一个 ...
- Java中的读/写锁
原文链接 作者:Jakob Jenkov 译者:微凉 校对:丁一 相比Java中的锁(Locks in Java)里Lock实现,读写锁更复杂一些.假设你的程序中涉及到对一些共享资源的读和写操作,且写 ...
- go中的读写锁RWMutex
转自:http://studygolang.com/articles/3027 读写锁是针对于读写操作的互斥锁. 基本遵循两大原则: 1.可以随便读.多个goroutin同时读. 2.写的时候,啥都不 ...
- Gox语言中使用读写锁解决并发冲突以及如何实现线程同步归并-GX22
Gox语言中,除了可以直接使用Go语言中的通道对象(chan)之外,也直接引入了Go语言标准库中的sync包,因此可以直接使用共享锁Mutex对象或者读写锁RWMutex对象来处理并发操作中共享数据安 ...
- java 读写锁_Java中的读写锁
一.读写锁 1.初识读写锁 a)Java中的锁--Lock和synchronized中介绍的ReentrantLock和synchronized基本上都是排它锁,意味着这些锁在同一时刻只允许一个线程进 ...
- Mysql中的读写锁,表锁和行锁,间隙锁
Mysql数据库锁 锁是计算机协调多个进程或线程并发访问某一资源的机制. 在数据库中,除传统的计算资源(如CPU.RAM.I/O等)的争用以外,数据也是一种供许多用户共享的资源.如何保证数据并发访问的 ...
- PHP程序中的文件锁、互斥锁、读写锁使用技巧解析
文件锁全名叫 advisory file lock, 书中有提及. 这类锁比较常见,例如 mysql, php-fpm 启动之后都会有一个pid文件记录了进程id,这个文件就是文件锁. 这个锁可以防止 ...
- ReentrantReadWriteLock读写锁及其在 RxCache 中的使用
一. ReentrantReadWriteLock读写锁 Lock 是相当于 synchronized 更面向对象的同步方式,ReentrantLock 是 Lock 的实现. 本文要介绍的 Reen ...
最新文章
- 绿联 蓝牙适配器 linux,绿联蓝牙适配器
- sql server 修改表结构语法大全
- matlab与vc混合编程指导书.doc,vc与matlab混合编程—基于com.doc
- WPF 学习笔记(十二)
- php jquery ajax实现用户名,php+jquery+ajax实现用户名验证
- c语言判断二叉树是不是二叉排序树_判断
- 计算机中常用的声音编辑工具有哪些,电脑常用音频剪辑软件
- EAS 后台事务配置
- 如何在电脑上实现企业微信多开?
- 板卡(单片机)与电脑PING不通的原因及解决方法
- Veil-Evasion安装及使用
- 数字类型与列表——python
- Android学习笔记---集成百度语音合成的坑与坑
- 数字人民币真的来了 六年历程全回顾
- 【图论】图的最短路径问题——有权图的单源最短路(Dijkstra算法)
- CSDN创作中心Markdown编辑器基本使用方法
- C++头文件和源文件的编译过程
- 使用sklearn划分训练集、验证集、测试集
- 6D姿态估计算法汇总
- TI公司DSP集成开发环境(CCS)有哪几种工作模式?各自特点是什么?