Функция atomic.SwapPointer
Функция atomic.SwapPointer выполняет атомарную замену значения указателя в многопоточном окружении. Эта функция гарантирует, что операция записи будет выполнена полностью и без прерываний другими горутинами. В первый параметр передается указатель на значение типа unsafe.Pointer, во второй параметр передается новое значение типа unsafe.Pointer, которое нужно установить, а возвращает функция старое значение указателя.
Синтаксис
atomic.SwapPointer(addr *unsafe.Pointer, new unsafe.Pointer) unsafe.Pointer
Пример
Давайте выполним атомарную замену значения указателя на новое значение:
package main
import (
"fmt"
"sync/atomic"
"unsafe"
)
func main() {
var ptr unsafe.Pointer
oldValue := "old"
newValue := "new"
atomic.StorePointer(&ptr, unsafe.Pointer(&oldValue))
old := atomic.SwapPointer(&ptr, unsafe.Pointer(&newValue))
fmt.Println(*(*string)(old))
fmt.Println(*(*string)(ptr))
}
Результат выполнения кода:
"old"
"new"
Пример
Давайте используем атомарную замену указателя для безопасного обновления конфигурации в многопоточном приложении:
package main
import (
"fmt"
"sync"
"sync/atomic"
"unsafe"
)
type Config struct {
Value string
}
func main() {
var configPtr unsafe.Pointer
initialConfig := &Config{Value: "v1"}
atomic.StorePointer(&configPtr, unsafe.Pointer(initialConfig))
var wg sync.WaitGroup
wg.Add(2)
// Горутина читает конфигурацию
go func() {
defer wg.Done()
for i := 0; i < 3; i++ {
cfg := (*Config)(atomic.LoadPointer(&configPtr))
fmt.Printf("Read: %s\n", cfg.Value)
}
}()
// Горутина обновляет конфигурацию
go func() {
defer wg.Done()
newConfig := &Config{Value: "v2"}
old := atomic.SwapPointer(&configPtr, unsafe.Pointer(newConfig))
fmt.Printf("Swapped from %s to %s\n", (*Config)(old).Value, newConfig.Value)
}()
wg.Wait()
}
Результат выполнения кода:
"Swapped from v1 to v2"
"Read: v2"
"Read: v1"
"Read: v2"
Смотрите также
-
функцию
atomic.SwapInt32,
которая выполняет атомарную замену значенияint32 -
функцию
atomic.CompareAndSwapPointer,
которая атомарно сравнивает и заменяет значение указателя -
функцию
atomic.LoadPointer,
которая атомарно читает значение указателя -
функцию
atomic.StorePointer,
которая атомарно записывает значение указателя