Метод sync.RWMutex.RUnlock
Метод sync.RWMutex.RUnlock освобождает блокировку чтения,
ранее захваченную методом RLock. Этот метод должен
вызываться после того, как чтение критической секции завершено.
Он уменьшает счетчик активных читателей на единицу. Метод не
возвращает никакого значения.
Важно помнить, что вызов RUnlock без предварительного
вызова RLock приводит к панике во время выполнения
программы. Поэтому всегда нужно использовать RUnlock
в паре с RLock.
Синтаксис
mu.RUnlock()
Пример
Давайте рассмотрим базовый пример использования
RUnlock для освобождения блокировки чтения:
package main
import (
"fmt"
"sync"
)
func main() {
var mu sync.RWMutex
data := "initial value"
mu.RLock()
fmt.Println("Reading data:", data)
mu.RUnlock()
}
Результат выполнения кода:
"Reading data: initial value"
Пример
Давайте рассмотрим пример использования RUnlock
в горутинах для безопасного чтения данных:
package main
import (
"fmt"
"sync"
"time"
)
func main() {
var mu sync.RWMutex
counter := 0
var wg sync.WaitGroup
for i := 0; i < 5; i++ {
wg.Add(1)
go func(id int) {
defer wg.Done()
mu.RLock()
fmt.Printf("Goroutine %d read: %d\n", id, counter)
mu.RUnlock()
}(i)
}
wg.Wait()
}
Результат выполнения кода:
"Goroutine 4 read: 0"
"Goroutine 0 read: 0"
"Goroutine 1 read: 0"
"Goroutine 2 read: 0"
"Goroutine 3 read: 0"
Пример
Давайте рассмотрим пример, где несколько горутин одновременно читают данные, а одна горутина их изменяет:
package main
import (
"fmt"
"sync"
"time"
)
func main() {
var mu sync.RWMutex
value := "initial"
var wg sync.WaitGroup
wg.Add(3)
go func() {
defer wg.Done()
mu.RLock()
fmt.Println("Reader 1:", value)
mu.RUnlock()
}()
go func() {
defer wg.Done()
time.Sleep(100 * time.Millisecond)
mu.Lock()
value = "updated"
fmt.Println("Writer updated value")
mu.Unlock()
}()
go func() {
defer wg.Done()
time.Sleep(50 * time.Millisecond)
mu.RLock()
fmt.Println("Reader 2:", value)
mu.RUnlock()
}()
wg.Wait()
}
Результат выполнения кода:
"Reader 1: initial"
"Reader 2: initial"
"Writer updated value"
Пример
Давайте рассмотрим пример использования RUnlock
с отложенным вызовом через defer для обеспечения
безопасного освобождения блокировки:
package main
import (
"fmt"
"sync"
)
func main() {
var mu sync.RWMutex
data := []string{"a", "b", "c", "d", "e"}
readData := func() {
mu.RLock()
defer mu.RUnlock()
for i, v := range data {
fmt.Printf("Index %d: %s\n", i, v)
}
}
readData()
}
Результат выполнения кода:
"Index 0: a"
"Index 1: b"
"Index 2: c"
"Index 3: d"
"Index 4: e"
Смотрите также
-
метод
sync.RWMutex.RLock,
который захватывает блокировку чтения -
метод
sync.RWMutex.Lock,
который захватывает блокировку записи -
метод
sync.RWMutex.Unlock,
который освобождает блокировку записи -
структуру
sync.RWMutex,
которая реализует блокировки чтения-записи