Go 使用普通鎖實現讀寫鎖

比較粗糙簡單,思路就是用一個mutex作爲資源鎖,用兩個整數記錄讀者數和寫者數,用一個內部鎖保護這個兩個整數和mutex,讀寫操作互斥,寫寫操作互斥,讀讀操作不互斥。

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()
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章