РЕПЕТИТОР математика физика информатика
Для школьников и студентов. Подтягивание пробелов. ЦЭ, ЦТ, ОГЭ, ЕГЭ.
Идет набор на ЛЕТО. Жмите для подробностей:)
895 of 1593 menu

Тип atomic.Int64

Тип atomic.Int64 представляет 64-битное целое число, с которым можно безопасно работать из разных горутин без использования мьютексов. Этот тип предоставляет методы для атомарного чтения, записи, сложения и сравнения значений. Данный тип находится в пакете sync/atomic и является рекомендуемой альтернативой функциям вида atomic.LoadInt64 и atomic.StoreInt64, так как предоставляет более удобный и типобезопасный интерфейс.

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

Синтаксис

Для использования типа atomic.Int64 необходимо импортировать пакет sync/atomic. Создается переменная типа atomic.Int64, после чего можно вызывать ее методы.

var counter atomic.Int64 counter.Add(10) val := counter.Load()

Метод Add - атомарное сложение

Метод Add прибавляет переданное значение к текущему значению atomic.Int64 и возвращает новое значение. Этот метод работает атомарно и эквивалентен операции atomic.AddInt64.

package main import ( "fmt" "sync" "sync/atomic" ) func main() { var counter atomic.Int64 var wg sync.WaitGroup for i := 0; i < 100; i++ { wg.Add(1) go func() { defer wg.Done() newVal := counter.Add(1) fmt.Printf("New value: %d\n", newVal) }() } wg.Wait() fmt.Printf("Final counter: %d\n", counter.Load()) }

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

"New value: 1" "New value: 2" ... "New value: 100" "Final counter: 100"

Метод Load - атомарное чтение

Метод Load атомарно возвращает текущее значение atomic.Int64. Он гарантирует, что чтение будет выполнено целостно, без промежуточных состояний, и эквивалентен функции atomic.LoadInt64.

package main import ( "fmt" "sync/atomic" ) func main() { var value atomic.Int64 value.Store(42) res := value.Load() fmt.Printf("Loaded value: %d\n", res) }

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

"Loaded value: 42"

Метод Store - атомарная запись

Метод Store атомарно устанавливает новое значение для atomic.Int64. Эта операция эквивалентна функции atomic.StoreInt64 и гарантирует, что запись будет выполнена атомарно, без промежуточных состояний.

package main import ( "fmt" "sync/atomic" ) func main() { var value atomic.Int64 value.Store(100) fmt.Printf("Stored value: %d\n", value.Load()) }

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

"Stored value: 100"

Метод Swap - атомарная замена

Метод Swap атомарно устанавливает новое значение и возвращает предыдущее. Эта операция эквивалентна функции atomic.SwapInt64 и полезна, когда нужно получить старое значение в момент замены.

package main import ( "fmt" "sync/atomic" ) func main() { var value atomic.Int64 value.Store(10) old := value.Swap(20) fmt.Printf("Old value: %d, New value: %d\n", old, value.Load()) }

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

"Old value: 10, New value: 20"

Метод CompareAndSwap - атомарное сравнение с заменой

Метод CompareAndSwap сравнивает текущее значение с ожидаемым и, если они равны, устанавливает новое значение. Операция возвращает true, если замена произошла. Этот метод эквивалентен функции atomic.CompareAndSwapInt64 и является основой для реализации lock-free алгоритмов.

package main import ( "fmt" "sync/atomic" ) func main() { var value atomic.Int64 value.Store(5) swapped := value.CompareAndSwap(5, 10) fmt.Printf("Swapped: %t, Value: %d\n", swapped, value.Load()) swapped = value.CompareAndSwap(5, 20) fmt.Printf("Swapped: %t, Value: %d\n", swapped, value.Load()) }

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

"Swapped: true, Value: 10" "Swapped: false, Value: 10"

Пример использования в счетчике

Рассмотрим практический пример использования atomic.Int64 для создания потокобезопасного счетчика, который инкрементируется из нескольких горутин:

package main import ( "fmt" "sync" "sync/atomic" ) type Counter struct { value atomic.Int64 } func (c *Counter) Inc() int64 { return c.value.Add(1) } func (c *Counter) Get() int64 { return c.value.Load() } func main() { counter := &Counter{} var wg sync.WaitGroup for i := 0; i < 50; i++ { wg.Add(1) go func() { defer wg.Done() for j := 0; j < 10; j++ { counter.Inc() } }() } wg.Wait() fmt.Printf("Total count: %d\n", counter.Get()) }

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

"Total count: 500"

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

  • тип atomic.Int32,
    предоставляющий атомарные операции для 32-битных целых чисел
  • тип atomic.Uint64,
    предоставляющий атомарные операции для беззнаковых 64-битных целых чисел
  • функцию atomic.AddInt64,
    которая атомарно прибавляет значение к int64
  • тип atomic.Bool,
    предоставляющий атомарные операции для булевых значений
Мы используем cookie для работы сайта, аналитики и персонализации. Обработка данных происходит согласно Политике конфиденциальности.
принять все настроить отклонить