Функция atomic.AddUint32

Функция atomic.AddUint32 атомарно прибавляет указанное значение к переменной типа uint32 и возвращает обновленное значение. Первым параметром функция принимает указатель на переменную типа uint32, которую нужно изменить. Вторым параметром передается значение типа uint32, которое нужно прибавить. Операция выполняется как единая неделимая инструкция процессора, что гарантирует корректность при конкурентном доступе.

Синтаксис

goatomic.AddUint32(addr *uint32, delta uint32) uint32

Пример

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

gopackage main

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

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

  for i := 0; i < 2; i++ {
    wg.Add(1)
    go func() {
      defer wg.Done()
      for j := 0; j < 100; j++ {
        newVal := atomic.AddUint32(&counter, 1)
        fmt.Println("New counter value:", newVal)
      }
    }()
  }

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

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

goNew counter value: 1
New counter value: 3
New counter value: 2
New counter value: 4
...
Final counter value: 200

Пример

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

gopackage main

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

func main() {
  var value uint32 = 100
  var wg sync.WaitGroup

  // Уменьшаем значение на 10
  for i := 0; i < 5; i++ {
    wg.Add(1)
    go func() {
      defer wg.Done()
      // Для вычитания используем дополнение до двух
      newVal := atomic.AddUint32(&value, ^uint32(9))
      fmt.Println("New value:", newVal)
    }()
  }

  wg.Wait()
  fmt.Println("Final value:", value)
}

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

goNew value: 90
New value: 80
New value: 70
New value: 60
New value: 50
Final value: 50

Обратите внимание, что для вычитания из значения типа uint32 используется выражение ^uint32(n-1), где n - число, которое нужно вычесть.

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

  • функцию atomic.AddInt32,
    которая атомарно прибавляет значение к переменной типа int32
  • функцию atomic.AddInt64,
    которая атомарно прибавляет значение к переменной типа int64
  • функцию atomic.AddUint64,
    которая атомарно прибавляет значение к переменной типа uint64
  • механизм sync.Mutex,
    который обеспечивает взаимоисключающую блокировку для безопасного доступа к данным из разных горутин