Функция atomic.CompareAndSwapInt32

Функция atomic.CompareAndSwapInt32 выполняет атомарную операцию сравнения и замены (CAS) для значения типа int32. В первый параметр (указатель) передается адрес переменной, значение которой нужно сравнить и при необходимости заменить. Во второй параметр передается ожидаемое значение (старое), с которым сравнивается текущее значение переменной. В третий параметр передается новое значение, которое будет записано в переменную, если текущее значение равно ожидаемому. Функция возвращает true, если замена была выполнена, и false, если текущее значение не совпало с ожидаемым (операция не выполнена).

Синтаксис

goatomic.CompareAndSwapInt32(addr, old, new)

Пример успешной замены

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

gopackage main

import (
  "fmt"
  "sync/atomic"
)

func main() {
  var x int32 = 10
  swapped := atomic.CompareAndSwapInt32(&x, 10, 42)
  fmt.Println(swapped)
  fmt.Println(x)
}

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

gotrue
42

Пример неуспешной замены

А теперь попробуем выполнить замену, когда текущее значение не совпадает с ожидаемым:

gopackage main

import (
  "fmt"
  "sync/atomic"
)

func main() {
  var x int32 = 10
  swapped := atomic.CompareAndSwapInt32(&x, 5, 42)
  fmt.Println(swapped)
  fmt.Println(x)
}

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

gofalse
10

Использование в цикле для атомарного обновления

Часто atomic.CompareAndSwapInt32 используется в цикле для надежного атомарного изменения значения, если операция не требует вызова функции с получением старого значения:

gopackage main

import (
  "fmt"
  "sync/atomic"
)

func main() {
  var x int32 = 5
  old := x

  for !atomic.CompareAndSwapInt32(&x, old, old+1) {
    old = x
  }

  fmt.Println(x)
}

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

go6

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

  • функцию atomic.CompareAndSwapInt64,
    которая работает с 64-битными целыми числами
  • функцию atomic.SwapInt32,
    которая атомарно заменяет значение без проверки
  • функцию atomic.LoadInt32,
    которая атомарно читает значение
  • функцию atomic.StoreInt32,
    которая атомарно записывает новое значение