Sobes.tech
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)
}