Middle
Какви типове мютекси предоставя стандартната библиотека на Go?
sobes.tech AI
Отговор от 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("Четене на данни: %s\n", data)
rwMutex.RUnlock() // Отключване за четене
}
func writeData(newData string) {
rwMutex.Lock() // Заключване за писане
data = newData
fmt.Printf("Писане на данни: %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)
}