This is because multiple goroutines compete for the same map. There are two ways to solve this problem, one is to use sync.Map, and the other is to lock. sync.map is a new feature added in go1.9, which will not be discussed here for now. Moreover, the current business scenario can be completely solved with read-write locks, so we decided to use read-write locks.
Read-write lock
RWMutex is a read-write lock. This lock can add multiple read locks or one write lock. It is often used in scenarios where the number of reads is much greater than the number of writes. (Recommended learning: go)
func (rw *RWMutex) Lock() Write lock, if there are other read locks and write locks before adding the write lock, the lock will Block until the lock is available. To ensure that the lock is eventually available, the blocked Lock call will exclude new readers from the acquired lock, that is, the write lock permission is higher than the read lock. When there is a write lock, the write lock is given priority
func (rw *RWMutex) Unlock() Unlock the write lock. If the write lock is not performed, a runtime error will occur
func (rw *RWMutex) RLock () Read lock. When there is a write lock, the read lock cannot be loaded. When there is only a read lock or no lock, the read lock can be loaded. Multiple read locks can be loaded, so it is suitable for the scenario of "more reading and less writing"
func (rw *RWMutex) RUnlock() Unlocks the read lock. RUnlock cancels a single RLock call. It has no effect on other readers that exist at the same time. If rw is not locked for reading, calling RUnlock will cause a runtime error
Summary:
Read locks cannot block read locks
Read locks need to block write locks until all read locks are released
Write locks need to block read locks until all write locks are released
Write locks need to block write locks
Up code:
type MapWithLock struct { //把读写锁和资源map封装在一起 sync.RWMutex M map[string]Kline } var KlineDataMemory = make(map[string] interface{}) var InstrLock sync.RWMutex var counter = MapWithLock{ // 生成一个带有锁和map的实例,然后就可以使用啦 InstrLock, KlineDataMemory, } . . . counter.RLock() //加读锁 for _, v := range counter.M { instrID = v.InstrumentID break } counter.RUnlock() //解除读锁 加锁和解锁必须成对出现,并且建议放在同一层次的代码块中
The above is the detailed content of What is the use of golang read lock?. For more information, please follow other related articles on the PHP Chinese website!