Goは通常のロックを使用して読み取り/書き込みロックを実装します

ラフでシンプルなアイデアは、ミューテックスをリソースロックとして使用し、2つの整数を使用してリーダーとライターの数を記録し、内部ロックを使用して2つの整数とミューテックスを保護することです。読み取りと書き込みの操作は相互に排他的です。と書き込み操作は相互に排他的ですが、読み取り読み取り操作は相互に排他的ではありません。

type RWMutex struct {
    
    
	mu  sync.Mutex  // 锁定资源的锁
	lock   sync.Mutex  // 保护读者数和写者数的锁
	reader int
	writer int
}

func (rwm *RWMutex) RLock() {
    
    
	// 在写锁已被锁定的情况下试图锁定读锁,会阻塞当前的goroutine
WAIT:
	for rwm.writer > 0 {
    
    
		time.Sleep(time.Millisecond * 1)
	}

	rwm.lock.Lock()
	// double check
	if rwm.writer > 0 {
    
    
		rwm.lock.Unlock()
		goto WAIT
	}
	// 在读锁已被锁定的情况下再试图锁定读锁,并不会阻塞当前的 goroutine
	if rwm.reader > 0 {
    
    
		rwm.reader++
		rwm.lock.Unlock()
		return
	}

	rwm.reader++
	rwm.mu.Lock()
	rwm.lock.Unlock()
}

func (rwm *RWMutex) RUnlock() {
    
    
	rwm.lock.Lock()
	if rwm.reader > 1 {
    
    
		rwm.reader--
		rwm.lock.Unlock()
		return
	}

	rwm.reader--
	rwm.mu.Unlock()
	rwm.lock.Unlock()
}

func (rwm *RWMutex) WLock() {
    
    
	// 在写锁已被锁定的情况下再试图锁定写锁,会阻塞当前的 goroutine。
	// 在读锁已被锁定的情况下试图锁定写锁,同样会阻塞当前的 goroutine。
	WAIT:
	for rwm.reader > 0 || rwm.writer > 0 {
    
    
		time.Sleep(time.Millisecond * 1)
	}
	rwm.lock.Lock()
	// double check
	if rwm.reader > 0 || rwm.writer > 0{
    
    
		rwm.lock.Unlock()
		goto WAIT
	}
	rwm.writer++
	rwm.mu.Lock()
	rwm.lock.Unlock()
}

func (rwm *RWMutex) WUnlock() {
    
    
	rwm.lock.Lock()
	rwm.writer--
	rwm.mu.Unlock()
	rwm.lock.Unlock()
}

おすすめ

転載: blog.csdn.net/qq_35753140/article/details/104848166