Network Security Internet Technology Development Database Servers Mobile Phone Android Software Apple Software Computer Software News IT Information

In addition to Weibo, there is also WeChat

Please pay attention

WeChat public account

Shulou

How to understand the implementation and core principles of read-write locks in golang

2025-01-16 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Servers >

Share

Shulou(Shulou.com)06/01 Report--

How to understand the golang read-write lock implementation and core principles, many novices are not very clear about this, in order to help you solve this problem, the following editor will explain for you in detail, people with this need can come to learn, I hope you can gain something.

The characteristics of the read-write lock of the foundation

The main difference between read-write lock and mutex lock is that read lock is shared, multiple goroutine can add read lock at the same time, but write lock and write lock, write lock and read lock are mutually exclusive.

Write lock hunger problem

Because the read lock is shared, if there is already a read lock, then the subsequent goroutine can add the read lock successfully under normal circumstances, but if there is a read lock all the time, the goroutine who tries to add the write lock may not get the lock for a long time. This is the hunger problem of the write lock caused by the read lock.

Implementation based on high and low bit and waiting queue

Before talking about golang, this paper introduces an implementation in JAVA. In JAVA, the ReentrantReadWriteLock implementation uses a high or low bit of state to count read and write locks, in which 16 bits store the count of reads and writes, and cooperate with an AQS to implement the queuing mechanism. At the same time, each waiter in AQS has a status to identify its own state.

Implementation member variables of golang's read-write lock

Structure type RWMutex struct {w Mutex / / held if there are pending writers writerSem uint32 / / semaphore for writer queuing for read completion readerSem uint32 / / counters for reader for semaphore readerCount int32 / / read lock for write completion queue readerWait int32 / / number of read locks waiting for read lock release} write lock count

The maximum number of read locks allowed in read-write locks is 4294967296. In go, the number of write locks is negative, and the write locks preempt read locks by decreasing the maximum number of read locks allowed.

Const rwmutexMaxReaders = 1 = rwmutexMaxReaders {race.Enable () throw ("sync: Unlock of unlocked RWMutex")} / / Wake up all read locks for I: = 0; I

< int(r); i++ { runtime_Semrelease(&rw.readerSem, false) } // 释放mutex rw.w.Unlock() if race.Enabled { race.Enable() }}关键核心机制写锁对读锁的抢占 加写锁的抢占 // 在加写锁的时候通过将readerCount递减最大允许加读锁的数量,来实现对加读锁的抢占 r := atomic.AddInt32(&rw.readerCount, -rwmutexMaxReaders) + rwmutexMaxReaders 加读锁的抢占检测 // 如果没有写锁的情况下读锁的readerCount进行Add后一定是一个>

If atomic.AddInt32 (& rw.readerCount, 1) < 0 {/ / A writer is pending, wait for it. Runtime_SemacquireMutex (& rw.readerSem, false)}

After the write lock preempts the read lock, the subsequent read lock will fail, but if you want to add the write lock successfully, you have to continue to wait for the read lock that has been successfully added.

If r! = 0 & & atomic.AddInt32 (& rw.readerWait, r)! = 0 {/ / write locks found that the number of read locks to be released is not zero, so they went to sleep on their own runtime_SemacquireMutex (& rw.writerSem, false)}

Since the write lock is dormant, there must be a wake-up mechanism, that is, every time the lock is released, when a write lock is detected, the readerWait is decremented, and the last goroutine that releases the reader lock is used to wake up the write lock.

If atomic.AddInt32 (& rw.readerWait,-1) = 0 {/ / The last reader unblocks the writer. Fairness of runtime_Semrelease (& rw.writerSem, false)} write Lock

When adding a write lock, mutex must be locked first, while mutex itself is unfair in normal mode and fair only in hunger mode.

Fairness of rw.w.Lock () write Lock and read Lock

Atomic.AddInt32 is used for increment in both read lock and write lock projects, and this instruction will lock the CPU bus through LOCK at the bottom, so there is only one success for multiple CPU to execute readerCount at the same time. From this point of view, it is relatively fair between write lock and read lock. Whoever reaches first is dispatched and executed by CPU first, and LOCK lock cache line succeeds.

Visibility and atomicity

In concurrency scenarios, especially in JAVA, two problems in concurrency are usually mentioned: visibility and memory barrier, atomicity, in which visibility usually refers to how to ensure cache consistency under cpu multi-level cache, that is, if a data is modified on one CPU, it will not continue to read old data on other CPU. Memory barrier is usually for CPU to reorder instructions in order to improve pipelined performance. Atomicity refers to the indivisibility of the process of performing an operation.

CPU instructions implemented at the bottom

There is no volatile keyword in go, so how can we ensure that the above AddInt32 operation can meet the above two problems? in fact, the key lies in the bottom two instructions, through the LOCK instruction with CPU's MESI protocol to achieve visibility and memory barrier, while through XADDL is used to ensure atomicity, so as to solve the visibility and atomicity problems mentioned above.

/ / atomic/asm_amd64.s TEXT runtime ∕ internal ∕ atomic ·Xadd (SB) LOCK XADDL AX, 0 (BX) is it helpful for you to read the above content? If you want to know more about the relevant knowledge or read more related articles, please follow the industry information channel, thank you for your support.

Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.

Views: 0

*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.

Share To

Servers

Wechat

© 2024 shulou.com SLNews company. All rights reserved.

12
Report