これは、複数のゴルーチンが同じマップをめぐって競合するためです。この問題を解決するには 2 つの方法があります。1 つは sync.Map を使用することで、もう 1 つはロックを使用することです。 sync.map は go1.9 で追加された新機能ですが、ここでは今のところ説明しません。さらに、現在のビジネス シナリオは読み取り/書き込みロックで完全に解決できるため、読み取り/書き込みロックを使用することにしました。
読み取り/書き込みロック
RWMutex は読み取り/書き込みロックです。このロックは複数の読み取りロックまたは 1 つの書き込みロックを追加できます。読み取り回数が書き込み回数よりはるかに多いシナリオでよく使用されます。 (推奨学習: go)
func (rw *RWMutex) Lock() 書き込みロック。書き込みロックを追加する前に他の読み取りロックと書き込みロックがある場合、ロックはブロックされるまでブロックされます。ロックが最終的に利用可能になることを保証するために、ブロックされた Lock 呼び出しは、取得したロックから新しいリーダーを除外します。つまり、書き込みロックのアクセス許可が読み取りロックよりも高くなります。書き込みロックがある場合、書き込みロックは、ロックを優先します
func (rw *RWMutex) Unlock() 書き込みロックを解除します 書き込みロックを行わないと実行時エラーが発生します
func (rw *RWMutex) RLock () 読み取りロック。書き込みロックがある場合、読み取りロックはロードできません。読み取りロックのみまたはロックがない場合、読み取りロックはロードできます。複数の読み取りロックをロードできます。したがって、「読み取りが多く、書き込みが少ない」というシナリオに適しています
func (rw *RWMutex) RUnlock() 読み取りロックのロックを解除します。 RUnlock は単一の RLock 呼び出しをキャンセルします。同時に存在する他のリーダー。 rw が読み取り用にロックされていない場合、RUnlock を呼び出すと実行時エラーが発生します。
概要:
読み取りロックは読み取りロックをブロックできません
読み取りロックが必要ですすべての読み取りロックが解放されるまで書き込みロックをブロックする
すべての書き込みロックが解放されるまで書き込みロックは読み取りロックをブロックする必要がある
書き込みロックは書き込みロックをブロックする必要がある
アップコード:
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() //解除读锁 加锁和解锁必须成对出现,并且建议放在同一层次的代码块中
以上がgolang の読み取りロックの用途は何ですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。