Функция atomic.StoreUint32

Функция atomic.StoreUint32 из пакета sync/atomic выполняет атомарную запись значения типа uint32 в указанную переменную. В первый параметр передается указатель на переменную, в которую нужно записать значение (тип *uint32), во второй параметр передается новое значение, которое необходимо сохранить. Атомарность гарантирует, что запись будет видна всем горутинам одновременно, без возможности чтения промежуточного состояния.

Синтаксис

goatomic.StoreUint32(addr *uint32, val uint32)

Пример

Давайте создадим переменную типа uint32 и атомарно запишем в нее значение 100:

gopackage main

import (
  "fmt"
  "sync/atomic"
)

func main() {
  var num uint32 = 10
  atomic.StoreUint32(&num, 100)
  fmt.Println(num)
}

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

go100

Пример

Давайте рассмотрим использование atomic.StoreUint32 в конкурентной среде. В этом примере несколько горутин одновременно пытаются записать значения, но атомарная операция гарантирует корректность:

gopackage main

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

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

  for i := 0; i < 10; i++ {
    wg.Add(1)
    go func(i int) {
      defer wg.Done()
      atomic.StoreUint32(&counter, uint32(i))
    }(i)
  }

  wg.Wait()
  fmt.Println("Counter:", counter)
}

Результат выполнения кода (может быть разным из-за порядка выполнения горутин):

go"Counter: 9"

Пример

Давайте используем atomic.StoreUint32 для атомарной записи флага состояния, например, для управления потоком выполнения в нескольких горутинах:

gopackage main

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

func main() {
  var flag uint32 = 0
  var wg sync.WaitGroup

  wg.Add(1)
  go func() {
    defer wg.Done()
    for {
      if atomic.LoadUint32(&flag) == 1 {
        fmt.Println("Flag is set, exiting worker")
        return
      }
      time.Sleep(100 * time.Millisecond)
    }
  }()

  time.Sleep(500 * time.Millisecond)
  atomic.StoreUint32(&flag, 1)

  wg.Wait()
  fmt.Println("Main done")
}

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

go"Flag is set, exiting worker"
"Main done"

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

  • функцию atomic.LoadUint32,
    которая атомарно загружает значение из переменной
  • функцию atomic.AddUint32,
    которая атомарно прибавляет значение к переменной
  • функцию atomic.CompareAndSwapUint32,
    которая атомарно сравнивает и заменяет значение
  • тип atomic.Uint32,
    который предоставляет удобную обертку для атомарных операций