Sobes.tech
Middle+

Операҳои атомӣ чист, кадом намудҳо доранд ва кай ва чӣ гуна беҳтар аст истифода бурдан?

sobes.tech AI

Ҷавоб аз AI

Операциите върху паметта, които гарантират, че ще завършат напълно или изобщо няма да започнат, без да могат да бъдат прекъсвани от други конкуриращи се операции, се наричат атомарни операции. Те са неделими и потокобезопасни на хардуерно ниво.

В Go пакетът sync/atomic предоставя набор от функции за изпълнение на атомарни операции:

Функция Описание
AddInt32 Атомарно добавя стойност към int32.
AddInt64 Атомарно добавя стойност към int64.
AddUint32 Атомарно добавя стойност към uint32.
AddUint64 Атомарно добавя стойност към uint64.
AddUintptr Атомарно добавя стойност към uintptr.
CompareAndSwapInt32 Атомарно сравнява и обменя (CAS) int32.
CompareAndSwapInt64 Атомарно сравнява и обменя (CAS) int64.
CompareAndSwapUint32 Атомарно сравнява и обменя (CAS) uint32.
CompareAndSwapUint64 Атомарно сравнява и обменя (CAS) uint64.
CompareAndSwapUintptr Атомарно сравнява и обменя (CAS) uintptr.
CompareAndSwapPointer Атомарно сравнява и обменя (CAS) unsafe.Pointer.
LoadInt32 Атомарно зарежда стойност int32.
LoadInt64 Атомарно зарежда стойност int64.
LoadUint32 Атомарно зарежда стойност uint32.
LoadUint64 Атомарно зарежда стойност uint64.
LoadUintptr Атомарно зарежда стойност uintptr.
LoadPointer Атомарно зарежда стойност unsafe.Pointer.
StoreInt32 Атомарно съхранява стойност int32.
StoreInt64 Атомарно съхранява стойност int64.
StoreUint32 Атомарно съхранява стойност uint32.
StoreUint64 Атомарно съхранява стойност uint64.
StoreUintptr Атомарно съхранява стойност uintptr.
StorePointer Атомарно съхранява стойност unsafe.Pointer.
SwapInt32 Атомарно обмени стойности int32.
SwapInt64 Атомарно обмени стойности int64.
SwapUint32 Атомарно обмени стойности uint32.
SwapUint64 Атомарно обмени стойности uint64.
SwapUintptr Атомарно обмени стойности uintptr.
SwapPointer Атомарно обмени стойности unsafe.Pointer.

Използването на атомарни операции е най-добре в случаи, когато е необходима проста, нискоуровнева синхронизация на достъпа до общи променливи, най-често броячи или флагове, без използване на мьютекси. Те осигуряват минимални разходи и по-добра производителност в сравнение с мьютексите в такива сценарии.

Пример за използване на атомарен брояч:

package main

import (
	"fmt"
	"sync"
	"sync/atomic"
)

func main() {
	var counter int64
	var wg sync.WaitGroup

	for i := 0; i < 100; i++ {
		wg.Add(1)
		go func() {
			// Атомарно увеличаваме брояча
			atomic.AddInt64(&counter, 1)
			wg.Done()
		}()
	}

	wg.Wait()
	// Атомарно зареждаме стойността на брояча
	fmt.Println("Final Counter:", atomic.LoadInt64(&counter))
}

Пример за използване CompareAndSwap:

package main

import (
	"fmt"
	"sync/atomic"
)

func main() {
	var value int32 = 10

	// Опит за обмен, ако текущото е 10, на 20
	swapped := atomic.CompareAndSwapInt32(&value, 10, 20)
	fmt.Println("Swapped:", swapped) // Swapped: true
	fmt.Println("Value:", value)   // Value: 20

	// Опит за обмен, ако текущото е 10, на 30
	swapped = atomic.CompareAndSwapInt32(&value, 10, 30)
	fmt.Println("Swapped:", swapped) // Swapped: false
	fmt.Println("Value:", value)   // Value: 20
}