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

Тип atomic.Pointer

Тип atomic.Pointer из пакета sync/atomic предоставляет атомарный указатель на значение любого типа. Он позволяет безопасно читать и изменять указатель из нескольких горутин без использования блокировок. Основные методы типа: Load для атомарного чтения, Store для атомарной записи, Swap для атомарной замены с возвратом старого значения и CompareAndSwap для условной атомарной замены.

Синтаксис

var ptr atomic.Pointer[T] ptr.Store(value) value := ptr.Load() old := ptr.Swap(new) swapped := ptr.CompareAndSwap(old, new)

Пример с Load и Store

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

package main import ( "fmt" "sync/atomic" ) func main() { var ptr atomic.Pointer[string] // Store value initial := "hello" ptr.Store(&initial) // Load value value := ptr.Load() fmt.Println(*value) // Store new value new := "world" ptr.Store(&new) // Load new value value = ptr.Load() fmt.Println(*value) }

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

"hello" "world"

Пример со Swap

Метод Swap атомарно заменяет указатель на новое значение и возвращает старое:

package main import ( "fmt" "sync/atomic" ) func main() { var ptr atomic.Pointer[string] first := "first" ptr.Store(&first) // Swap old value with new second := "second" old := ptr.Swap(&second) fmt.Println("Old value:", *old) fmt.Println("New value:", *ptr.Load()) }

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

"Old value: first" "New value: second"

Пример с CompareAndSwap

Метод CompareAndSwap выполняет атомарную замену только если текущее значение указателя совпадает с ожидаемым:

package main import ( "fmt" "sync/atomic" ) func main() { var ptr atomic.Pointer[string] current := "current" ptr.Store(¤t) expected := "current" new := "updated" // This will succeed swapped := ptr.CompareAndSwap(&expected, &new) fmt.Println("Swapped:", swapped) fmt.Println("Value:", *ptr.Load()) // This will fail expected = "wrong" new = "another" swapped = ptr.CompareAndSwap(&expected, &new) fmt.Println("Swapped:", swapped) fmt.Println("Value:", *ptr.Load()) }

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

"Swapped: true" "Value: updated" "Swapped: false" "Value: updated"

Пример с использованием в горутинах

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

package main import ( "fmt" "sync" "sync/atomic" "time" ) func main() { var ptr atomic.Pointer[string] var wg sync.WaitGroup initial := "initial" ptr.Store(&initial) // Writer goroutine wg.Add(1) go func() { defer wg.Done() time.Sleep(100 * time.Millisecond) updated := "updated" ptr.Store(&updated) fmt.Println("Writer: stored new value") }() // Reader goroutines for i := 0; i < 3; i++ { wg.Add(1) go func(id int) { defer wg.Done() time.Sleep(50 * time.Millisecond) value := ptr.Load() fmt.Printf("Reader %d: %s\n", id, *value) }(i) } wg.Wait() }

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

"Reader 2: initial" "Reader 0: initial" "Reader 1: initial" "Writer: stored new value"

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

  • тип atomic.Value,
    который предоставляет атомарное хранилище для значений любого типа
  • тип atomic.Bool,
    который предоставляет атомарный булевый тип
  • тип sync.Mutex,
    который обеспечивает взаимное исключение для защиты данных
  • пакет go,
    который используется для запуска горутин в Go
Мы используем cookie для работы сайта, аналитики и персонализации. Обработка данных происходит согласно Политике конфиденциальности.
принять все настроить отклонить