当前位置: 首页 > news >正文

广州网站建设电话咨询谷歌google play官网

广州网站建设电话咨询,谷歌google play官网,百度网页版浏览器,企业邮箱可以是个人qq邮箱吗go读写锁的实现原理 1、RWMutex读写锁的概念 读写锁也就是我们所使用的RWMutex,其实是对于go本身的mutex做的一个拓展,当一个goroutine获得了读锁后,其他goroutine同样可以获得读锁,但是不能获得写锁。相反,当一个go…

go读写锁的实现原理

1、RWMutex读写锁的概念

读写锁也就是我们所使用的RWMutex,其实是对于go本身的mutex做的一个拓展,当一个goroutine获得了读锁后,其他goroutine同样可以获得读锁,但是不能获得写锁。相反,当一个goroutine获得了写锁,其他goroutine既不能读也不能写,互斥的概念。

2、使用场景

适用于读多写少的情况

3、底层实现

读写锁实现的结构体位于src下的sync包下的rwmutex.go文件中

type RWMutex struct {w           Mutex  // held if there are pending writerswriterSem   uint32 // semaphore for writers to wait for completing readersreaderSem   uint32 // semaphore for readers to wait for completing writersreaderCount int32  // number of pending readersreaderWait  int32  // number of departing readers
}	

w字段代表着复用了互斥锁

writerSem代表写信号量,用于写等待读

readerSem代表读信号量,用于读等待写

readerCount代表当前执行读的goroutine数量

readerWait代表被阻塞的准备读的goroutine的数量

4、读锁的实现

加读锁

func (rw *RWMutex) RLock() {if atomic.AddInt32(&rw.readerCount, 1) < 0 {// A writer is pending, wait for it.runtime_SemacquireMutex(&rw.readerSem, false, 0)}
}

首先看这个if方法,为什么要判断小于0呢?

atomic.AddInt32(&rw.readerCount, 1) < 0调用的这个原子方法,目的就是当goroutine加读锁的时候读锁数量+1,如果返回的数量是负数,那么就代表了当前有其他写锁,这个时候就掉用runtime_SemacquireMutex方法休眠当前goroutine,readerSem就记录者这个goroutine。所以要判断是否小于0

释放读锁

// RUnlock undoes a single RLock call;
// it does not affect other simultaneous readers.
// It is a run-time error if rw is not locked for reading
// on entry to RUnlock.
func (rw *RWMutex) RUnlock() {if r := atomic.AddInt32(&rw.readerCount, -1); r < 0 {// Outlined slow-path to allow the fast-path to be inlinedrw.rUnlockSlow(r)}
}

释放读锁的时候就是对readerCount读数量-1即可,如果返回值小于0,就代表着当前有写的操作,这个时候就会调用rUnlockSlow进入慢速通道

什么是慢速通道

func (rw *RWMutex) rUnlockSlow(r int32) {// A writer is pending.if atomic.AddInt32(&rw.readerWait, -1) == 0 {// The last reader unblocks the writer.runtime_Semrelease(&rw.writerSem, false, 1)}
}

被阻塞的准备读的goroutine数量-1,如果readerWait为0,就表示当前没有goroutine正在准备读,这个时候去唤醒写操作

5、写锁的实现

加写锁

const rwmutexMaxReaders = 1 << 30
// Lock locks rw for writing.
// If the lock is already locked for reading or writing,
// Lock blocks until the lock is available.
func (rw *RWMutex) Lock() {// First, resolve competition with other writers.rw.w.Lock()// Announce to readers there is a pending writer.r := atomic.AddInt32(&rw.readerCount, -rwmutexMaxReaders) + rwmutexMaxReaders// Wait for active readers.if r != 0 && atomic.AddInt32(&rw.readerWait, r) != 0 {runtime_SemacquireMutex(&rw.writerSem, false, 0)}
}

写锁的调用就是调用互斥锁w的lock,如果计算之后还是有其他goroutine持有读锁,那么就调用runtime_SemacquireMutex休眠当前的goroutine等待所有的读操作完成, atomic.AddInt32(&rw.readerCount, -rwmutexMaxReaders) + rwmutexMaxReaders这个操作目的是防止后面的goroutine拿到读锁,阻塞读的作用。

释放写锁

// Unlock unlocks rw for writing. It is a run-time error if rw is
// not locked for writing on entry to Unlock.
//
// As with Mutexes, a locked RWMutex is not associated with a particular
// goroutine. One goroutine may RLock (Lock) a RWMutex and then
// arrange for another goroutine to RUnlock (Unlock) it.
func (rw *RWMutex) Unlock() {// Announce to readers there is no active writer.r := atomic.AddInt32(&rw.readerCount, rwmutexMaxReaders)if r >= rwmutexMaxReaders {race.Enable()fatal("sync: Unlock of unlocked RWMutex")}// Unblock blocked readers, if any.for i := 0; i < int(r); i++ {runtime_Semrelease(&rw.readerSem, false, 0)}// Allow other writers to proceed.rw.w.Unlock()
}

当释放写锁的时候,首先会通过atomic.AddInt32(&rw.readerCount, rwmutexMaxReaders)恢复之前的写入的很大的那个负数,然后看当前有多少个读操作在等待,循环唤醒等待读的goroutine

注意:go中的锁不支持可重入锁,若想实现可自定义实现

6、总结

读写锁区分读锁和写锁,而普通的互斥锁不区分,读写锁主要应用在读多写少的场景,既保证了并发读的执行效率,又保证了线程之间的安全。

http://www.yayakq.cn/news/742200/

相关文章:

  • php企业网站开发方案南通网站建设top
  • 福州企业建站软件综合信息网站模板
  • 用英文字母做网站关键词有没有网站教做美食的
  • 网站服务器计算机安全的措施广告公司视频制作
  • 爱站权重是怎么计算的做爰午夜福利全过程视频网站
  • 深圳做网站龙华新科商旅通官网app
  • 网站业务费如何做记账凭证做软件赚钱吗
  • 建站公司是什么wordpress word上传
  • 企业网站怎么做才好.net商城网站开发
  • 厦门云端企业网站建设成都 php 网站
  • 外国做挂的网站是多少网站建设招标技术要求
  • 三门峡 网站开发旅游网站案例
  • 上海松江建设发展有限公司网站食品公司网站源码
  • 礼品类网站建设策划方案装修网站论坛
  • c2c电商平台网站网站开发待遇怎么样
  • 网站制作后还能更改么家在深圳坪山业主论坛
  • h5 建站网站 移动端网站建设与管理代码题
  • 广西南宁公司网站制作百度搜索什么关键词排名
  • 建设项目网站备案申请表金华市住房建设局网站
  • 深圳专业手机网站建设网络推广网站推广方法
  • 安新seo优化排名网站专业的建站
  • php游戏网站建设高质量的网站建设
  • 如何做带后台的网站太原广告设计与制作公司
  • 网站建设与管理试卷A搭建 wiki wordpress
  • 安徽网站建设开发电话nginx wordpress 404.php
  • 中医院网站源码百度蜘蛛如何找网站
  • 用别的公司域名做网站n怎样建立自己的网站
  • 网站开发的著作权归谁为什么选择做网站编辑
  • 集团网站建设服务公司网站做等报定级工作要多久
  • 长沙响应式网站建设国外电商网站建设