Функция atomic.SwapUint32
Функция atomic.SwapUint32 выполняет атомарный обмен значений
для переменной типа uint32. Она принимает указатель на
переменную для обмена и новое значение, которое требуется установить.
Функция возвращает предыдущее значение переменной до обмена.
Эта операция гарантирует, что чтение старого значения и запись нового
выполняются как единое неделимое действие, что критически важно
в конкурентном программировании для безопасного обновления общих данных.
Синтаксис
atomic.SwapUint32(addr *uint32, new uint32) (old uint32)
Где addr — указатель на переменную типа uint32,
в которую будет записано новое значение, а new — новое значение.
Функция возвращает старое значение, которое хранилось до вызова.
Пример
Давайте выполним атомарный обмен значения для переменной типа uint32
в конкурентной среде:
package main
import (
"fmt"
"sync"
"sync/atomic"
)
func main() {
var counter uint32 = 100
var wg sync.WaitGroup
wg.Add(1)
go func() {
defer wg.Done()
old := atomic.SwapUint32(&counter, 200)
fmt.Printf("old value: %d, new value: %d\n", old, counter)
}()
wg.Wait()
fmt.Printf("final counter: %d\n", counter)
}
Результат выполнения кода:
"old value: 100, new value: 200"
"final counter: 200"
В данном примере горутина атомарно меняет значение переменной
counter с 100 на 200 и возвращает предыдущее значение 100.
Пример
Используем atomic.SwapUint32 для безопасного обновления счётчика
в нескольких горутинах:
package main
import (
"fmt"
"sync"
"sync/atomic"
)
func main() {
var value uint32 = 42
var wg sync.WaitGroup
for i := 0; i < 5; i++ {
wg.Add(1)
go func(newVal uint32) {
defer wg.Done()
old := atomic.SwapUint32(&value, newVal)
fmt.Printf("goroutine set %d, old was %d\n", newVal, old)
}(uint32(i * 10))
}
wg.Wait()
fmt.Printf("final value: %d\n", value)
}
Результат выполнения кода:
"goroutine set 0, old was 42"
"goroutine set 10, old was 0"
"goroutine set 20, old was 10"
"goroutine set 30, old was 20"
"goroutine set 40, old was 30"
"final value: 40"
Каждая горутина атомарно устанавливает новое значение и получает
предыдущее. Операция SwapUint32 гарантирует, что все
изменения выполняются последовательно, и ни одно из них не будет потеряно.
Смотрите также
-
функцию
atomic.SwapInt32,
которая выполняет атомарный обмен для типаint32 -
функцию
atomic.LoadUint32,
которая атомарно загружает значение типаuint32 -
функцию
atomic.StoreUint32,
которая атомарно сохраняет значение типаuint32 -
функцию
atomic.CompareAndSwapUint32,
которая сравнивает и обменивает значение типаuint32