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 mutex mutex in Go

2025-02-24 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Servers >

Share

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

How to understand the mutex mutex in Go, I believe many inexperienced people don't know what to do about it. Therefore, this paper summarizes the causes and solutions of the problem. Through this article, I hope you can solve this problem.

1. The basic concept of lock 1.1 CAS and polling 1.1.1 cas implement lock

In the implementation of lock, more and more people use CAS to acquire lock by using the CAS instruction of processor to exchange the value of a given variable.

1.1.2 polling lock

In the case of multi-thread concurrency, it is very likely that a thread CAS will fail, which is usually used in conjunction with the for loop to try to re-acquire the lock by polling.

1.2 Fairness of locks

Locks are usually divided into fair locks and unfair locks in terms of fairness, which mainly depends on whether the thread that acquires the lock first acquires the lock earlier than the subsequent thread in the process of lock acquisition. if so, it is a fair lock: multiple threads acquire locks in the order in which they acquire locks, otherwise it is unfair.

1.3 Hunger and queue 1.3.1 Lock Hunger

Lock hunger means that because a large number of threads acquire locks at the same time, some threads may fail during the lock's CAS process, thus failing to acquire the lock for a long time.

1.3.2 queuing mechanism

It is mentioned above that CAS and polling locks are used to acquire locks. It can be found that if a thread has acquired the lock, but when the current thread fails to obtain the lock by polling for many times, there is no need to continue to make repeated attempts to waste system resources. A queuing mechanism is usually used to queue and wait.

1.4 bit count

When implementing CAS-based locks in most programming languages, a 32-bit integer is usually used to store the lock state.

2. Mutex implementation 2.1 member variables and pattern 2.1.1 member variables

In the mutex of go, there are only two core member variables, state and sema, which count locks through state and queue through sema.

Type Mutex struct {state int32 sema uint32} 2.1.2 Lock Mode

There are mainly two kinds of lock modes.

Describe fairness normal mode under normal mode all goroutine acquire locks according to the order of FIFO, the awakened goroutine and the newly requested lock goroutine acquire locks at the same time, usually the newly requested lock goroutine is easier to acquire locks No Hunger mode all goroutine trying to acquire locks are queued, the goroutine of new request locks will not do lock acquisition, but join the queue and wait for the lock to be acquired.

As you can see above, in normal mode, the performance of locks is the highest. If multiple goroutine are released immediately after lock acquisition, the queuing consumption of multiple threads can be avoided. Similarly, after switching to hunger mode, when lock acquisition is carried out, it will switch back to normal mode if certain conditions are met, thus ensuring the high performance of locks.

2.2 Lock count 2.2.1 Lock status

There are three flag bits in mutex, among which the binary bits are 001 (mutexLocked), 010 (mutexWoken) and 100 (mutexStarving). Note that these three are not mutually exclusive, for example, the state of a lock may be in locked hunger mode and has been awakened.

MutexLocked = 1 > mutexWaiterShift! = 0: move 3 bits to the right, if not 0 It indicates that there is a waiting goroutine / / atomic.CompareAndSwapInt32 (& m.state, old, old | mutexWoken) that sets the current state to wake up if! awoke & & old&mutexWoken = = 0 & old > > mutexWaiterShift! = 0 & & atomic.CompareAndSwapInt32 (& m.state, old) Old | mutexWoken) {awoke = true} / / attempt to spin Runtime_doSpin () / / spin count iter++ / / get the state from the new old = m.state continue} 2.3.3 change the lock state

There are two possibilities for the process to come here: 1. The lock state is no longer locked state 2. Spin exceeds the specified number of times, spin is no longer allowed

New: = old if old&mutexStarving = = 0 {/ / if the current mode is not hunger Then you can actually try to acquire the lock here | = set the bit bit of the lock to 1 to indicate the lock status new | = mutexLocked} if old& (mutexLocked | mutexStarving)! = 0 {/ / if it is currently locked or in hunger mode Then wait for a wait count new + = 1 starvationThresholdNs / / reacquire status old = m.state if old&mutexStarving! = 0 {/ / if it is found that the current mode is already hungry Note that hunger mode wakes up the first goroutine / / currently all goroutine are waiting in queue / / consistency check If old& (mutexLocked | mutexWoken)! = 0 | | old > > mutexWaiterShift = = 0 {throw ("sync: inconsistent mutex state")} / / get the current mode Delta: = int32 (mutexLocked-1mutexWaiterShift = = 1 {/ / if the current goroutine is not hungry Switching from hunger mode to normal mode / / then switching out of mutexStarving state delta-= mutexStarving} / / finally performing cas operation atomic.AddInt32 (& m.state) Delta) break} / / reset count awoke = true iter = 0} else {old = m.state} 2.5 release lock logic

2.5.1 release lock code func (m * Mutex) Unlock () {if race.Enabled {_ = m.state race.Release (unsafe.Pointer (m))} / / perform cas operation directly new: = atomic.AddInt32 (& m.state) -mutexLocked) if (new+mutexLocked) & mutexLocked = = 0 {throw ("sync: unlock of unlocked mutex")} if new&mutexStarving = = 0 {/ / if the lock is released and it is not in hunger mode old: = new for {if old > > mutexWaiterShift = = 0 | old& (mutexLocked | mutexWoken | mutexStarving) ! = 0 {/ / if there is already a waiting person and has been awakened Just return return} / / minus a wait count, and then switch the current mode to mutexWoken new = (old-1)

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