简介

互斥锁本质是当一个协程访问的时候,其他协程都不能访问.
其实主要是想:修改数据要同步,这样其他协程才可以感知到,所以真正的互斥应该是读取和修改,修改和修改之间,读和读是没有互斥操作的必要的

读写锁可以让多个读并发,但是对于写是互斥的.
当一个协程在写的时候,其他协程不能读也不能写
同时只能存在写锁定或读锁定(读和写互斥)

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中的读写锁相关推荐

  1. golang中关于读写锁、互斥锁的理解

    锁的概述 为了解决协程同步的问题我们使用了channel,但是GO也提供了传统的同步工具. 它们都在GO的标准库代码包sync和sync/atomic中. 下面我们看一下锁的应用. 什么是锁呢?就是某 ...

  2. MongoDB中的读写锁

    1. MongoDB 使用的锁 MongoDB 使用的是"readers-writer"锁, 可以支持并发但有很大的局限性 当一个读锁存在,许多读操作可以使用这把锁,然而, 当一个 ...

  3. Java中的读/写锁

    原文链接 作者:Jakob Jenkov 译者:微凉 校对:丁一 相比Java中的锁(Locks in Java)里Lock实现,读写锁更复杂一些.假设你的程序中涉及到对一些共享资源的读和写操作,且写 ...

  4. go中的读写锁RWMutex

    转自:http://studygolang.com/articles/3027 读写锁是针对于读写操作的互斥锁. 基本遵循两大原则: 1.可以随便读.多个goroutin同时读. 2.写的时候,啥都不 ...

  5. Gox语言中使用读写锁解决并发冲突以及如何实现线程同步归并-GX22

    Gox语言中,除了可以直接使用Go语言中的通道对象(chan)之外,也直接引入了Go语言标准库中的sync包,因此可以直接使用共享锁Mutex对象或者读写锁RWMutex对象来处理并发操作中共享数据安 ...

  6. java 读写锁_Java中的读写锁

    一.读写锁 1.初识读写锁 a)Java中的锁--Lock和synchronized中介绍的ReentrantLock和synchronized基本上都是排它锁,意味着这些锁在同一时刻只允许一个线程进 ...

  7. Mysql中的读写锁,表锁和行锁,间隙锁

    Mysql数据库锁 锁是计算机协调多个进程或线程并发访问某一资源的机制. 在数据库中,除传统的计算资源(如CPU.RAM.I/O等)的争用以外,数据也是一种供许多用户共享的资源.如何保证数据并发访问的 ...

  8. PHP程序中的文件锁、互斥锁、读写锁使用技巧解析

    文件锁全名叫 advisory file lock, 书中有提及. 这类锁比较常见,例如 mysql, php-fpm 启动之后都会有一个pid文件记录了进程id,这个文件就是文件锁. 这个锁可以防止 ...

  9. ReentrantReadWriteLock读写锁及其在 RxCache 中的使用

    一. ReentrantReadWriteLock读写锁 Lock 是相当于 synchronized 更面向对象的同步方式,ReentrantLock 是 Lock 的实现. 本文要介绍的 Reen ...

最新文章

  1. 绿联 蓝牙适配器 linux,绿联蓝牙适配器
  2. sql server 修改表结构语法大全
  3. matlab与vc混合编程指导书.doc,vc与matlab混合编程—基于com.doc
  4. WPF 学习笔记(十二)
  5. php jquery ajax实现用户名,php+jquery+ajax实现用户名验证
  6. c语言判断二叉树是不是二叉排序树_判断
  7. 计算机中常用的声音编辑工具有哪些,电脑常用音频剪辑软件
  8. EAS 后台事务配置
  9. 如何在电脑上实现企业微信多开?
  10. 板卡(单片机)与电脑PING不通的原因及解决方法
  11. Veil-Evasion安装及使用
  12. 数字类型与列表——python
  13. Android学习笔记---集成百度语音合成的坑与坑
  14. 数字人民币真的来了 六年历程全回顾
  15. 【图论】图的最短路径问题——有权图的单源最短路(Dijkstra算法)
  16. CSDN创作中心Markdown编辑器基本使用方法
  17. C++头文件和源文件的编译过程
  18. 使用sklearn划分训练集、验证集、测试集
  19. 6D姿态估计算法汇总
  20. TI公司DSP集成开发环境(CCS)有哪几种工作模式?各自特点是什么?

热门文章

  1. MySQL查询日志介绍
  2. poj 3984
  3. 3创建型模式之单例模式
  4. 线程的创建 验证线程之间共享数据 守护线程 线程进程效率对比 锁 死锁 递归锁...
  5. bit_length
  6. java 入门-helloWorld
  7. [NOIP2017]逛公园 最短路+拓扑排序+dp
  8. layoutSubviews何时被调用
  9. jquery技巧总结 学习
  10. stl.map使用总结