Функция atomic.AddInt32
Функция atomic.AddInt32 выполняет атомарное сложение
указанного значения с 32-битным целым числом. В первый параметр
мы передаем указатель на переменную типа int32, которую
нужно изменить, во второй параметр мы передаем значение типа
int32, которое необходимо прибавить к текущему значению.
Функция возвращает новое значение после сложения.
Синтаксис
atomic.AddInt32(addr *int32, delta int32) int32
Функция атомарно добавляет delta к значению по адресу
addr и возвращает обновленное значение. Операция
выполняется без блокировок, что делает её более эффективной
по сравнению с использованием мьютексов для простых счетчиков.
Пример использования в горутинах
Давайте создадим счетчик, который будет инкрементироваться
несколькими горутинами с использованием atomic.AddInt32:
package main
import (
"fmt"
"sync"
"sync/atomic"
)
func main() {
var counter int32
var wg sync.WaitGroup
for i := 0; i < 10; i++ {
wg.Add(1)
go func() {
defer wg.Done()
for j := 0; j < 100; j++ {
atomic.AddInt32(&counter, 1)
}
}()
}
wg.Wait()
fmt.Println(counter)
}
Результат выполнения кода:
1000
В этом примере 10 горутин параллельно инкрементируют счетчик
100 раз каждая. Благодаря использованию atomic.AddInt32,
финальное значение всегда будет корректным и равным 1000.
Пример с отрицательным приращением
Функция поддерживает как положительные, так и отрицательные значения для приращения. Давайте создадим счетчик, который будет уменьшаться:
package main
import (
"fmt"
"sync"
"sync/atomic"
)
func main() {
var counter int32 = 100
var wg sync.WaitGroup
for i := 0; i < 5; i++ {
wg.Add(1)
go func() {
defer wg.Done()
atomic.AddInt32(&counter, -10)
}()
}
wg.Wait()
fmt.Println(counter)
}
Результат выполнения кода:
50
Каждая из 5 горутин уменьшает счетчик на 10, поэтому финальное значение составляет 50. Операция атомарна и безопасна для параллельного использования.
Пример с использованием возвращаемого значения
Функция возвращает новое значение, что позволяет использовать его сразу после обновления:
package main
import (
"fmt"
"sync"
"sync/atomic"
)
func main() {
var counter int32 = 5
var wg sync.WaitGroup
var results []int32
for i := 0; i < 3; i++ {
wg.Add(1)
go func() {
defer wg.Done()
newValue := atomic.AddInt32(&counter, 2)
results = append(results, newValue)
}()
}
wg.Wait()
fmt.Println("Counter:", counter)
fmt.Println("Results:", results)
}
Возможный результат выполнения кода:
Counter: 11
Results: [7 9 11]
Каждая горутина получает уникальное новое значение счетчика, поскольку операция выполняется атомарно и возвращает результат после обновления.
Смотрите также
-
функцию
atomic.AddInt64,
которая выполняет атомарное сложение для 64-битных целых чисел -
функцию
atomic.LoadInt32,
которая атомарно загружает значение 32-битного целого числа -
функцию
atomic.StoreInt32,
которая атомарно сохраняет значение 32-битного целого числа -
тип
atomic.Int32,
который предоставляет структуру с методами для атомарных операций над int32