Функция atomic.StorePointer

Функция atomic.StorePointer выполняет атомарную запись значения указателя в указанную область памяти. Это гарантирует, что операция записи будет завершена полностью и другие горутины увидят новое значение указателя только после завершения записи. Первым параметром функция принимает указатель на unsafe.Pointer, в который нужно выполнить запись, вторым параметром - новое значение типа unsafe.Pointer, которое нужно сохранить.

Синтаксис

goatomic.StorePointer(addr *unsafe.Pointer, val unsafe.Pointer)

Пример

Давайте выполним атомарную запись указателя на строку в переменную:

gopackage main

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

func main() {
  var ptr unsafe.Pointer
  str := "hello"
  atomic.StorePointer(&ptr, unsafe.Pointer(&str))

  res := (*string)(ptr)
  fmt.Println(*res)
}

Результат выполнения кода:

go"hello"

Пример

Давайте выполним атомарную запись указателя на структуру с одновременным чтением из нескольких горутин:

gopackage main

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

type Config struct {
  Value string
}

func main() {
  var ptr unsafe.Pointer
  var wg sync.WaitGroup

  config := &Config{Value: "initial"}
  atomic.StorePointer(&ptr, unsafe.Pointer(config))

  for i := 0; i < 3; i++ {
    wg.Add(1)
    go func() {
      defer wg.Done()
      p := atomic.LoadPointer(&ptr)
      cfg := (*Config)(p)
      fmt.Println(cfg.Value)
    }()
  }

  newConfig := &Config{Value: "updated"}
  atomic.StorePointer(&ptr, unsafe.Pointer(newConfig))
  wg.Wait()
}

Результат выполнения кода:

go"initial"
"initial"
"updated"

Пример

Давайте выполним атомарную запись указателя с использованием цикла для обновления значения:

gopackage main

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

func main() {
  var ptr unsafe.Pointer
  initial := 100
  atomic.StorePointer(&ptr, unsafe.Pointer(&initial))

  for i := 0; i < 5; i++ {
    newVal := i * 10
    atomic.StorePointer(&ptr, unsafe.Pointer(&newVal))
  }

  res := (*int)(ptr)
  fmt.Println(*res)
}

Результат выполнения кода:

go40

Смотрите также

  • функцию atomic.LoadPointer,
    которая атомарно загружает значение указателя
  • функцию atomic.SwapPointer,
    которая атомарно обменивает значение указателя на новое и возвращает старое
  • функцию atomic.CompareAndSwapPointer,
    которая выполняет атомарное сравнение и замену значения указателя
  • тип atomic.Pointer,
    который предоставляет типизированный атомарный указатель