首页 > 其他分享 >RWMutex

RWMutex

时间:2024-08-05 15:52:53浏览次数:9  
标签:rw RWMutex readers sync Add runtime

package aa

import (
"sync"
"sync/atomic"
_ "unsafe"
)

const rwmutexMaxReaders = 1 << 30

type RWMutex struct {
w sync.Mutex // held if there are pending writers
writerSem uint32 // semaphore for writers to wait for completing readers
readerSem uint32 // semaphore for readers to wait for completing writers
readerCount atomic.Int32 // number of pending readers
readerWait atomic.Int32 // number of departing readers
}

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

func (rw *RWMutex) RUnlock() {
if r := rw.readerCount.Add(-1); r < 0 {
if r+1 == 0 || r+1 == -rwmutexMaxReaders {
panic("sync: RUnlock of unlocked RWMutex")
}
// A writer is pending.
if rw.readerWait.Add(-1) == 0 {
// The last reader unblocks the writer.
runtime_Semrelease(&rw.writerSem, false, 1)
}
}
}

func (rw *RWMutex) WLock() {
// First, resolve competition with other writers.
rw.w.Lock()
// Announce to readers there is a pending writer.
r := rw.readerCount.Add(-rwmutexMaxReaders) + rwmutexMaxReaders
// Wait for active readers.
if r != 0 && rw.readerWait.Add(r) != 0 {
runtime_SemacquireRWMutex(&rw.writerSem, false, 0)
}
}

func (rw *RWMutex) WUnlock() {
// Announce to readers there is no active writer.
r := rw.readerCount.Add(rwmutexMaxReaders)
if r >= rwmutexMaxReaders {
panic("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()
}

//go:linkname runtime_SemacquireRWMutexR sync.runtime_SemacquireRWMutexR
func runtime_SemacquireRWMutexR(s *uint32, lifo bool, skipframes int)

//go:linkname runtime_SemacquireRWMutex sync.runtime_SemacquireRWMutex

func runtime_SemacquireRWMutex(s *uint32, lifo bool, skipframes int)

//go:linkname runtime_Semrelease sync.runtime_Semrelease
func runtime_Semrelease(s *uint32, handoff bool, skipframes int)




func TestName22(t *testing.T) {
m := new(RWMutex)
m.RLock()
m.RLock()
go func() {
m.WLock()
fmt.Println("w acquired")
m.WUnlock()
}()
time.Sleep(1 * time.Second)
m.RUnlock()
m.RUnlock()
}

标签:rw,RWMutex,readers,sync,Add,runtime
From: https://www.cnblogs.com/Janly/p/18343354

相关文章

  • Go语言核心36讲 26 | sync.Mutex与sync.RWMutex
    我在前面用20多篇文章,为你详细地剖析了Go语言本身的一些东西,这包括了基础概念、重要语法、高级数据类型、特色语句、测试方案等等。这些都是Go语言为我们提供的最核心的技术。我想,这已经足够让你对Go语言有一个比较深刻的理解了。从本篇文章开始,我们将一起探讨Go语言自带标准......
  • 从源码深入理解读写锁(golang-RWMutex)
    环境:go1.19.8在读多写少的情况下,即使一段时间内没有写操作,大量并发的读访问也不得不在Mutex的保护下变成串行访问,这种情况下,使用Mutex,对性能影响比较大。所以就要区分读写操作。如果某个读操作的g持有了锁,其他读操作的g就不必等待了,可以并发的访问共享变量,这样就可以将串行的......
  • Go RWMutex:高并发读多写少场景下的性能优化利器
    原创文章,如需转载请联系作者:陈明勇公众号:Go技术干货前言在这篇文章GoMutex:保护并发访问共享资源的利器中,主要介绍了Go语言中互斥锁Mutex的概念、对应的字段与方法、基本使用和易错场景,最后基于Mutex实现一个简单的协程安全的缓存。而本文,我们来看看另一个更高效的......
  • Go语言并发编程(3):sync包介绍和使用(上)-Mutex,RWMutex,WaitGroup,sync.Map
    一、sync包简介在并发编程中,为了解决竞争条件问题,Go语言提供了sync标准包,它提供了基本的同步原语,例如互斥锁、读写锁等。sync包使用建议:除了Once和WaitGroup......
  • 【转】go Mutex (互斥锁)和RWMutex(读写锁)
    golang中sync包实现了两种锁Mutex(互斥锁)和RWMutex(读写锁),其中RWMutex是基于Mutex实现的,只读锁的实现使用类似引用计数器的功能.typeMutexfunc(m*Mutex)Lock(......
  • (转)golang常用库之-标准库 sync包| go语言如何实现单例模式、读写锁(sync.RWMutex)
    原文:https://blog.csdn.net/inthat/article/details/124218961golang常用库之-标准库sync包Golangsync包提供了基础的异步操作方法,包括互斥锁Mutex,执行一次Once和并发等......
  • go RWMutex源码分析
    适用场景并发场景下读多写少。字段含义RWMutex基于Mutex,写优先,Lock函数(反转readerCount)会阻止新的reader获取锁。typeRWMutexstruct{  wMutex  // writer......
  • golang Sync.Mutex互斥锁和Sync.RWMutex读写锁小结
    Sync.Mutex一、结构体typeMutexstruct{stateint32//互斥锁的状态:被g持有,空闲等semauint32//信号量,用于阻塞/唤醒goroutine(协程)}//使用varmtx......