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

品牌推广网站设计网站开发与网页设计大作业

品牌推广网站设计,网站开发与网页设计大作业,品牌营销策略分析论文,站外推广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/131830/

相关文章:

  • 网站做显卡评测软件简洁html网站模版
  • 商业网站策划方案网站做很多关键词
  • 海西高端网站建设公司宝塔wordpress更换域名
  • wordpress 网站 图标玩具网站建设规划书
  • 如何避免网站模板侵权全国前十名校程序开发公司
  • 贵阳双龙区建设局网站现在建网站做推广能赚钱吗
  • 淮安做网站就找卓越凯欣gif8.net基于wordpress
  • 学生处网站建设工作总结百度地图手机网站开发
  • 建设网站询价对比表模板中国三大生产建设兵团
  • 重庆营销型网站wordpress中英主题
  • 网站建设发布平台沈阳seo哪家公司
  • 网站建设大数据男女的做那个视频网站
  • 淘客返利怎么做网站电子商务网站建设情况
  • 网站建设好了还要收取维护费网站建设 网站维护
  • 建设的比较好的档案馆网站邢台网站设计
  • 微信导航网站怎么做南开网站建设优化seo
  • 深圳企业推广网站排名今鼎网站建设
  • 服务网站策划书wordpress 网站域名
  • 怎么自己创造网站好网站123
  • 旅游网站需求分析怎么做的北京网站开发网络公司
  • 万州网站制作页面设计简称
  • 淘宝客 备案 网站名称国家建设部防化工程师网站官网
  • 商城网站离不开支付系统问答社区网站建设
  • 网站建设兼职合同模板百度收录提交工具
  • 整站seo免费咨询sem和seo是什么意思
  • php语言 电商网站建设广西建设网桂建云官网
  • 58同城西安网站建设傻瓜式免费自助建站系统
  • 安全的网站建设服务wordpress 扫码插件
  • 网站建设实验七wordpress重新配置ftp
  • 海珠营销网站建设报价杭州最好的电商培训学校