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

Тип atomic.Uintptr

Тип atomic.Uintptr представляет собой атомарное беззнаковое целое, размер которого равен размеру указателя на данной архитектуре (например, 32 бита на 32-битных системах и 64 бита на 64-битных). Этот тип позволяет выполнять атомарные операции загрузки, сохранения, добавления, обмена и сравнения с обменом над значениями указателей. В качестве значения передается целое число, которое может быть интерпретировано как адрес памяти, а возвращаемое значение представляет собой текущее состояние счетчика или указателя. Основное назначение atomic.Uintptr — обеспечить потокобезопасную работу с указателями без использования тяжеловесных примитивов синхронизации, таких как мьютексы.

Синтаксис

var ptr atomic.Uintptr ptr.Store(uintptr(addr)) value := ptr.Load() old := ptr.Swap(uintptr(newAddr)) swapped := ptr.CompareAndSwap(old, uintptr(newAddr)) ptr.Add(uintptr(delta))

Пример

Давайте создадим атомарную переменную типа atomic.Uintptr, сохраним в нее адрес переменной, а затем загрузим его обратно:

package main import ( "fmt" "sync/atomic" "unsafe" ) func main() { var p atomic.Uintptr x := 42 addr := uintptr(unsafe.Pointer(&x)) p.Store(addr) loadedAddr := p.Load() loadedX := *(*int)(unsafe.Pointer(loadedAddr)) fmt.Println(loadedX) }

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

42

Пример

Теперь выполним атомарное добавление (смещение) к значению указателя. Это может быть полезно при работе с массивами или срезами:

package main import ( "fmt" "sync/atomic" "unsafe" ) func main() { var p atomic.Uintptr arr := []int{10, 20, 30, 40, 50} base := uintptr(unsafe.Pointer(&arr[0])) p.Store(base) // Смещаем указатель на размер одного элемента int // (на 64-битной системе это обычно 8 байт) p.Add(unsafe.Sizeof(arr[0])) newAddr := p.Load() val := *(*int)(unsafe.Pointer(newAddr)) fmt.Println(val) }

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

20

Пример

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

package main import ( "fmt" "sync/atomic" "unsafe" ) func main() { var p atomic.Uintptr a := 100 b := 200 addrA := uintptr(unsafe.Pointer(&a)) addrB := uintptr(unsafe.Pointer(&b)) p.Store(addrA) swapped := p.CompareAndSwap(addrA, addrB) fmt.Println(swapped) loaded := p.Load() val := *(*int)(unsafe.Pointer(loaded)) fmt.Println(val) }

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

true 200

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

  • тип atomic.Uint64,
    который предоставляет атомарные операции над 64-разрядными целыми
  • тип atomic.Pointer,
    который обеспечивает атомарную работу с типизированными указателями
  • функцию atomic.AddUintptr,
    которая атомарно прибавляет значение к переменной типа uintptr
  • функцию atomic.SwapPointer,
    которая атомарно обменивает значение указателя на новое
Мы используем cookie для работы сайта, аналитики и персонализации. Обработка данных происходит согласно Политике конфиденциальности.
принять все настроить отклонить