Назад к вопросам
Middle
104
questionbank
Какие типы мьютексов предоставляет стандартная библиотека Go?
Sobes Copilot
Получайте ответы в реальном времени
Ответ от нейросети
sobes.tech AI
Стандартная библиотека Go предоставляет два основных типа мьютексов в пакете sync:
sync.Mutex: Базовый мьютекс, обеспечивающий взаимоисключающую блокировку. Может быть в двух состояниях: заблокирован или разблокирован. Только одна горутина может удерживать блокировку в любой момент времени.sync.RWMutex: Мьютекс для чтения/записи. Позволяет множеству горутин одновременно читать данные (получать RLock), но только одной горутине писать данные (получать Lock). Запись блокирует все операции (как чтение, так и запись).
Основные методы sync.Mutex:
| Метод | Описание |
|---|---|
Lock() |
Блокирует мьютекс. Если мьютекс уже заблокирован, вызывающая горутина блокируется до его освобождения. |
Unlock() |
Разблокирует мьютекс. Паника, если мьютекс не был заблокирован вызывающей горутиной. |
Основные методы sync.RWMutex:
| Метод | Описание |
|---|---|
Lock() |
Блокирует мьютекс для записи. Блокирует все операции чтения и записи. |
Unlock() |
Разблокирует мьютекс для записи. Паника, если мьютекс не был заблокирован для записи. |
RLock() |
Блокирует мьютекс для чтения. Не блокирует другие операции чтения. Блокируется, если есть блокировка записи. |
RUnlock() |
Разблокирует мьютекс для чтения. Паника, если мьютекс не был заблокирован для чтения. |
RLocker() |
Возвращает Locker, который использует RLock и RUnlock. |
Пример использования sync.Mutex:
package main
import (
"fmt"
"sync"
"time"
)
var counter int
var mutex sync.Mutex
func increment() {
mutex.Lock() // Блокируем мьютекс
counter++
fmt.Printf("Counter: %d\n", counter)
mutex.Unlock() // Разблокируем мьютекс
}
func main() {
for i := 0; i < 10; i++ {
go increment()
}
time.Sleep(time.Second) // Даем время горутинам завершиться
}
Пример использования sync.RWMutex:
package main
import (
"fmt"
"sync"
"time"
)
var data string
var rwMutex sync.RWMutex
func readData() {
rwMutex.RLock() // Блокируем для чтения
fmt.Printf("Reading data: %s\n", data)
rwMutex.RUnlock() // Разблокируем для чтения
}
func writeData(newData string) {
rwMutex.Lock() // Блокируем для записи
data = newData
fmt.Printf("Writing data: %s\n", data)
rwMutex.Unlock() // Разблокируем для записи
}
func main() {
go writeData("Hello")
time.Sleep(100 * time.Millisecond) // Даем время на запись
for i := 0; i < 5; i++ {
go readData() // Множество одновременных чтений разрешены
}
time.Sleep(time.Second) // Даем время горутинам завершиться
go writeData("World")
time.Sleep(100 * time.Millisecond)
go readData()
time.Sleep(time.Second)
}