Navigation Menu

Search code, repositories, users, issues, pull requests..., provide feedback.

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly.

To see all available qualifiers, see our documentation .

  • Notifications You must be signed in to change notification settings

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement . We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Is assigning a pointer atomic in go #38667

@SmallSmartMouse

SmallSmartMouse commented Apr 26, 2020

In my project,i encounter problems,this is my code:
`var data map[string]string

func main() {

}
data = temp` atomic ,and is there any problem or bug,

@randall77

randall77 commented Apr 26, 2020

This is a race condition, and is invalid code.
Run with the flag and you will see an error.

More generally, pointer assignment atomic, but you need more than that to make an example like yours work.

The Go project does not use the issue tracker for questions. Please use a forum for this discussion. See . Thanks.

Sorry, something went wrong.

@randall77

SmallSmartMouse commented Apr 29, 2020

Hi
In forum I dont get a response. In the example code,Is reassignment of the global data map with the temp one I created atomic?
Is the step of taking the address of the map,then assigning the address to the global map address pointer atomic?

thanks.

@lsytj0413

lsytj0413 commented Apr 29, 2020


In forum I dont get a response. In the example code,Is reassignment of the global data map with the temp one I created atomic?
Is the step of taking the address of the map,then assigning the address to the global map address pointer atomic?

thanks.

there is nothing about ,just about the exec order between two goroutine.

@ianlancetaylor

ianlancetaylor commented Apr 30, 2020

I'm sorry, this is still the wrong place to ask questions. If one forum didn't help, try a different one. Don't try back here. Sorry, and thanks for respecting our approach to questions.

@smallnest

No branches or pull requests

@ianlancetaylor

This package is not in the latest version of its module.

Documentation ¶

Package atomic provides low-level atomic memory primitives useful for implementing synchronization algorithms.

These functions require great care to be used correctly. Except for special, low-level applications, synchronization is better done with channels or the facilities of the sync package. Share memory by communicating; don't communicate by sharing memory.

The swap operation, implemented by the SwapT functions, is the atomic equivalent of:

The compare-and-swap operation, implemented by the CompareAndSwapT functions, is the atomic equivalent of:

The add operation, implemented by the AddT functions, is the atomic equivalent of:

The load and store operations, implemented by the LoadT and StoreT functions, are the atomic equivalents of "return *addr" and "*addr = val".

In the terminology of the Go memory model , if the effect of an atomic operation A is observed by atomic operation B, then A “synchronizes before” B. Additionally, all the atomic operations executed in a program behave as though executed in some sequentially consistent order. This definition provides the same semantics as C++'s sequentially consistent atomics and Java's volatile variables.

  • func AddInt32(addr *int32, delta int32) (new int32)
  • func AddInt64(addr *int64, delta int64) (new int64)
  • func AddUint32(addr *uint32, delta uint32) (new uint32)
  • func AddUint64(addr *uint64, delta uint64) (new uint64)
  • func AddUintptr(addr *uintptr, delta uintptr) (new uintptr)
  • func AndInt32(addr *int32, mask int32) (old int32)
  • func AndInt64(addr *int64, mask int64) (old int64)
  • func AndUint32(addr *uint32, mask uint32) (old uint32)
  • func AndUint64(addr *uint64, mask uint64) (old uint64)
  • func AndUintptr(addr *uintptr, mask uintptr) (old uintptr)
  • func CompareAndSwapInt32(addr *int32, old, new int32) (swapped bool)
  • func CompareAndSwapInt64(addr *int64, old, new int64) (swapped bool)
  • func CompareAndSwapPointer(addr *unsafe.Pointer, old, new unsafe.Pointer) (swapped bool)
  • func CompareAndSwapUint32(addr *uint32, old, new uint32) (swapped bool)
  • func CompareAndSwapUint64(addr *uint64, old, new uint64) (swapped bool)
  • func CompareAndSwapUintptr(addr *uintptr, old, new uintptr) (swapped bool)
  • func LoadInt32(addr *int32) (val int32)
  • func LoadInt64(addr *int64) (val int64)
  • func LoadPointer(addr *unsafe.Pointer) (val unsafe.Pointer)
  • func LoadUint32(addr *uint32) (val uint32)
  • func LoadUint64(addr *uint64) (val uint64)
  • func LoadUintptr(addr *uintptr) (val uintptr)
  • func OrInt32(addr *int32, mask int32) (old int32)
  • func OrInt64(addr *int64, mask int64) (old int64)
  • func OrUint32(addr *uint32, mask uint32) (old uint32)
  • func OrUint64(addr *uint64, mask uint64) (old uint64)
  • func OrUintptr(addr *uintptr, mask uintptr) (old uintptr)
  • func StoreInt32(addr *int32, val int32)
  • func StoreInt64(addr *int64, val int64)
  • func StorePointer(addr *unsafe.Pointer, val unsafe.Pointer)
  • func StoreUint32(addr *uint32, val uint32)
  • func StoreUint64(addr *uint64, val uint64)
  • func StoreUintptr(addr *uintptr, val uintptr)
  • func SwapInt32(addr *int32, new int32) (old int32)
  • func SwapInt64(addr *int64, new int64) (old int64)
  • func SwapPointer(addr *unsafe.Pointer, new unsafe.Pointer) (old unsafe.Pointer)
  • func SwapUint32(addr *uint32, new uint32) (old uint32)
  • func SwapUint64(addr *uint64, new uint64) (old uint64)
  • func SwapUintptr(addr *uintptr, new uintptr) (old uintptr)
  • func (x *Bool) CompareAndSwap(old, new bool) (swapped bool)
  • func (x *Bool) Load() bool
  • func (x *Bool) Store(val bool)
  • func (x *Bool) Swap(new bool) (old bool)
  • func (x *Int32) Add(delta int32) (new int32)
  • func (x *Int32) And(mask int32) (old int32)
  • func (x *Int32) CompareAndSwap(old, new int32) (swapped bool)
  • func (x *Int32) Load() int32
  • func (x *Int32) Or(mask int32) (old int32)
  • func (x *Int32) Store(val int32)
  • func (x *Int32) Swap(new int32) (old int32)
  • func (x *Int64) Add(delta int64) (new int64)
  • func (x *Int64) And(mask int64) (old int64)
  • func (x *Int64) CompareAndSwap(old, new int64) (swapped bool)
  • func (x *Int64) Load() int64
  • func (x *Int64) Or(mask int64) (old int64)
  • func (x *Int64) Store(val int64)
  • func (x *Int64) Swap(new int64) (old int64)
  • type Pointer
  • func (x *Pointer[T]) CompareAndSwap(old, new *T) (swapped bool)
  • func (x *Pointer[T]) Load() *T
  • func (x *Pointer[T]) Store(val *T)
  • func (x *Pointer[T]) Swap(new *T) (old *T)
  • type Uint32
  • func (x *Uint32) Add(delta uint32) (new uint32)
  • func (x *Uint32) And(mask uint32) (old uint32)
  • func (x *Uint32) CompareAndSwap(old, new uint32) (swapped bool)
  • func (x *Uint32) Load() uint32
  • func (x *Uint32) Or(mask uint32) (old uint32)
  • func (x *Uint32) Store(val uint32)
  • func (x *Uint32) Swap(new uint32) (old uint32)
  • type Uint64
  • func (x *Uint64) Add(delta uint64) (new uint64)
  • func (x *Uint64) And(mask uint64) (old uint64)
  • func (x *Uint64) CompareAndSwap(old, new uint64) (swapped bool)
  • func (x *Uint64) Load() uint64
  • func (x *Uint64) Or(mask uint64) (old uint64)
  • func (x *Uint64) Store(val uint64)
  • func (x *Uint64) Swap(new uint64) (old uint64)
  • type Uintptr
  • func (x *Uintptr) Add(delta uintptr) (new uintptr)
  • func (x *Uintptr) And(mask uintptr) (old uintptr)
  • func (x *Uintptr) CompareAndSwap(old, new uintptr) (swapped bool)
  • func (x *Uintptr) Load() uintptr
  • func (x *Uintptr) Or(mask uintptr) (old uintptr)
  • func (x *Uintptr) Store(val uintptr)
  • func (x *Uintptr) Swap(new uintptr) (old uintptr)
  • func (v *Value) CompareAndSwap(old, new any) (swapped bool)
  • func (v *Value) Load() (val any)
  • func (v *Value) Store(val any)
  • func (v *Value) Swap(new any) (old any)
  • Value (Config)
  • Value (ReadMostly)

Constants ¶

This section is empty.

Variables ¶

Functions ¶, func addint32 ¶.

AddInt32 atomically adds delta to *addr and returns the new value. Consider using the more ergonomic and less error-prone Int32.Add instead.

func AddInt64 ¶

AddInt64 atomically adds delta to *addr and returns the new value. Consider using the more ergonomic and less error-prone Int64.Add instead (particularly if you target 32-bit platforms; see the bugs section).

func AddUint32 ¶

AddUint32 atomically adds delta to *addr and returns the new value. To subtract a signed positive constant value c from x, do AddUint32(&x, ^uint32(c-1)). In particular, to decrement x, do AddUint32(&x, ^uint32(0)). Consider using the more ergonomic and less error-prone Uint32.Add instead.

func AddUint64 ¶

AddUint64 atomically adds delta to *addr and returns the new value. To subtract a signed positive constant value c from x, do AddUint64(&x, ^uint64(c-1)). In particular, to decrement x, do AddUint64(&x, ^uint64(0)). Consider using the more ergonomic and less error-prone Uint64.Add instead (particularly if you target 32-bit platforms; see the bugs section).

func AddUintptr ¶

AddUintptr atomically adds delta to *addr and returns the new value. Consider using the more ergonomic and less error-prone Uintptr.Add instead.

func AndInt32 ¶ added in go1.23.0

AndInt32 atomically performs a bitwise AND operation on *addr using the bitmask provided as mask and returns the old value. Consider using the more ergonomic and less error-prone Int32.And instead.

func AndInt64 ¶ added in go1.23.0

AndInt64 atomically performs a bitwise AND operation on *addr using the bitmask provided as mask and returns the old value. Consider using the more ergonomic and less error-prone Int64.And instead.

func AndUint32 ¶ added in go1.23.0

AndUint32 atomically performs a bitwise AND operation on *addr using the bitmask provided as mask and returns the old value. Consider using the more ergonomic and less error-prone Uint32.And instead.

func AndUint64 ¶ added in go1.23.0

AndUint64 atomically performs a bitwise AND operation on *addr using the bitmask provided as mask and returns the old. Consider using the more ergonomic and less error-prone Uint64.And instead.

func AndUintptr ¶ added in go1.23.0

AndUintptr atomically performs a bitwise AND operation on *addr using the bitmask provided as mask and returns the old value. Consider using the more ergonomic and less error-prone Uintptr.And instead.

func CompareAndSwapInt32 ¶

CompareAndSwapInt32 executes the compare-and-swap operation for an int32 value. Consider using the more ergonomic and less error-prone Int32.CompareAndSwap instead.

func CompareAndSwapInt64 ¶

CompareAndSwapInt64 executes the compare-and-swap operation for an int64 value. Consider using the more ergonomic and less error-prone Int64.CompareAndSwap instead (particularly if you target 32-bit platforms; see the bugs section).

func CompareAndSwapPointer ¶

CompareAndSwapPointer executes the compare-and-swap operation for a unsafe.Pointer value. Consider using the more ergonomic and less error-prone Pointer.CompareAndSwap instead.

func CompareAndSwapUint32 ¶

CompareAndSwapUint32 executes the compare-and-swap operation for a uint32 value. Consider using the more ergonomic and less error-prone Uint32.CompareAndSwap instead.

func CompareAndSwapUint64 ¶

CompareAndSwapUint64 executes the compare-and-swap operation for a uint64 value. Consider using the more ergonomic and less error-prone Uint64.CompareAndSwap instead (particularly if you target 32-bit platforms; see the bugs section).

func CompareAndSwapUintptr ¶

CompareAndSwapUintptr executes the compare-and-swap operation for a uintptr value. Consider using the more ergonomic and less error-prone Uintptr.CompareAndSwap instead.

func LoadInt32 ¶

LoadInt32 atomically loads *addr. Consider using the more ergonomic and less error-prone Int32.Load instead.

func LoadInt64 ¶

LoadInt64 atomically loads *addr. Consider using the more ergonomic and less error-prone Int64.Load instead (particularly if you target 32-bit platforms; see the bugs section).

func LoadPointer ¶

LoadPointer atomically loads *addr. Consider using the more ergonomic and less error-prone Pointer.Load instead.

func LoadUint32 ¶

LoadUint32 atomically loads *addr. Consider using the more ergonomic and less error-prone Uint32.Load instead.

func LoadUint64 ¶

LoadUint64 atomically loads *addr. Consider using the more ergonomic and less error-prone Uint64.Load instead (particularly if you target 32-bit platforms; see the bugs section).

func LoadUintptr ¶

LoadUintptr atomically loads *addr. Consider using the more ergonomic and less error-prone Uintptr.Load instead.

func OrInt32 ¶ added in go1.23.0

OrInt32 atomically performs a bitwise OR operation on *addr using the bitmask provided as mask and returns the old value. Consider using the more ergonomic and less error-prone Int32.Or instead.

func OrInt64 ¶ added in go1.23.0

OrInt64 atomically performs a bitwise OR operation on *addr using the bitmask provided as mask and returns the old value. Consider using the more ergonomic and less error-prone Int64.Or instead.

func OrUint32 ¶ added in go1.23.0

OrUint32 atomically performs a bitwise OR operation on *addr using the bitmask provided as mask and returns the old value. Consider using the more ergonomic and less error-prone Uint32.Or instead.

func OrUint64 ¶ added in go1.23.0

OrUint64 atomically performs a bitwise OR operation on *addr using the bitmask provided as mask and returns the old value. Consider using the more ergonomic and less error-prone Uint64.Or instead.

func OrUintptr ¶ added in go1.23.0

OrUintptr atomically performs a bitwise OR operation on *addr using the bitmask provided as mask and returns the old value. Consider using the more ergonomic and less error-prone Uintptr.Or instead.

func StoreInt32 ¶

StoreInt32 atomically stores val into *addr. Consider using the more ergonomic and less error-prone Int32.Store instead.

func StoreInt64 ¶

StoreInt64 atomically stores val into *addr. Consider using the more ergonomic and less error-prone Int64.Store instead (particularly if you target 32-bit platforms; see the bugs section).

func StorePointer ¶

StorePointer atomically stores val into *addr. Consider using the more ergonomic and less error-prone Pointer.Store instead.

func StoreUint32 ¶

StoreUint32 atomically stores val into *addr. Consider using the more ergonomic and less error-prone Uint32.Store instead.

func StoreUint64 ¶

StoreUint64 atomically stores val into *addr. Consider using the more ergonomic and less error-prone Uint64.Store instead (particularly if you target 32-bit platforms; see the bugs section).

func StoreUintptr ¶

StoreUintptr atomically stores val into *addr. Consider using the more ergonomic and less error-prone Uintptr.Store instead.

func SwapInt32 ¶ added in go1.2

SwapInt32 atomically stores new into *addr and returns the previous *addr value. Consider using the more ergonomic and less error-prone Int32.Swap instead.

func SwapInt64 ¶ added in go1.2

SwapInt64 atomically stores new into *addr and returns the previous *addr value. Consider using the more ergonomic and less error-prone Int64.Swap instead (particularly if you target 32-bit platforms; see the bugs section).

func SwapPointer ¶ added in go1.2

SwapPointer atomically stores new into *addr and returns the previous *addr value. Consider using the more ergonomic and less error-prone Pointer.Swap instead.

func SwapUint32 ¶ added in go1.2

SwapUint32 atomically stores new into *addr and returns the previous *addr value. Consider using the more ergonomic and less error-prone Uint32.Swap instead.

func SwapUint64 ¶ added in go1.2

SwapUint64 atomically stores new into *addr and returns the previous *addr value. Consider using the more ergonomic and less error-prone Uint64.Swap instead (particularly if you target 32-bit platforms; see the bugs section).

func SwapUintptr ¶ added in go1.2

SwapUintptr atomically stores new into *addr and returns the previous *addr value. Consider using the more ergonomic and less error-prone Uintptr.Swap instead.

type Bool ¶ added in go1.19

A Bool is an atomic boolean value. The zero value is false.

func (*Bool) CompareAndSwap ¶ added in go1.19

CompareAndSwap executes the compare-and-swap operation for the boolean value x.

func (*Bool) Load ¶ added in go1.19

Load atomically loads and returns the value stored in x.

func (*Bool) Store ¶ added in go1.19

Store atomically stores val into x.

func (*Bool) Swap ¶ added in go1.19

Swap atomically stores new into x and returns the previous value.

type Int32 ¶ added in go1.19

An Int32 is an atomic int32. The zero value is zero.

func (*Int32) Add ¶ added in go1.19

Add atomically adds delta to x and returns the new value.

func (*Int32) And ¶ added in go1.23.0

And atomically performs a bitwise AND operation on x using the bitmask provided as mask and returns the old value.

func (*Int32) CompareAndSwap ¶ added in go1.19

CompareAndSwap executes the compare-and-swap operation for x.

func (*Int32) Load ¶ added in go1.19

Func (*int32) or ¶ added in go1.23.0.

Or atomically performs a bitwise OR operation on x using the bitmask provided as mask and returns the old value.

func (*Int32) Store ¶ added in go1.19

Func (*int32) swap ¶ added in go1.19, type int64 ¶ added in go1.19.

An Int64 is an atomic int64. The zero value is zero.

func (*Int64) Add ¶ added in go1.19

Func (*int64) and ¶ added in go1.23.0, func (*int64) compareandswap ¶ added in go1.19, func (*int64) load ¶ added in go1.19, func (*int64) or ¶ added in go1.23.0, func (*int64) store ¶ added in go1.19, func (*int64) swap ¶ added in go1.19, type pointer ¶ added in go1.19.

A Pointer is an atomic pointer of type *T. The zero value is a nil *T.

func (*Pointer[T]) CompareAndSwap ¶ added in go1.19

Func (*pointer[t]) load ¶ added in go1.19, func (*pointer[t]) store ¶ added in go1.19, func (*pointer[t]) swap ¶ added in go1.19, type uint32 ¶ added in go1.19.

A Uint32 is an atomic uint32. The zero value is zero.

func (*Uint32) Add ¶ added in go1.19

Func (*uint32) and ¶ added in go1.23.0, func (*uint32) compareandswap ¶ added in go1.19, func (*uint32) load ¶ added in go1.19, func (*uint32) or ¶ added in go1.23.0, func (*uint32) store ¶ added in go1.19, func (*uint32) swap ¶ added in go1.19, type uint64 ¶ added in go1.19.

A Uint64 is an atomic uint64. The zero value is zero.

func (*Uint64) Add ¶ added in go1.19

Func (*uint64) and ¶ added in go1.23.0, func (*uint64) compareandswap ¶ added in go1.19, func (*uint64) load ¶ added in go1.19, func (*uint64) or ¶ added in go1.23.0, func (*uint64) store ¶ added in go1.19, func (*uint64) swap ¶ added in go1.19, type uintptr ¶ added in go1.19.

A Uintptr is an atomic uintptr. The zero value is zero.

func (*Uintptr) Add ¶ added in go1.19

Func (*uintptr) and ¶ added in go1.23.0, func (*uintptr) compareandswap ¶ added in go1.19, func (*uintptr) load ¶ added in go1.19, func (*uintptr) or ¶ added in go1.23.0.

Or atomically performs a bitwise OR operation on x using the bitmask provided as mask and returns the updated value after the OR operation.

func (*Uintptr) Store ¶ added in go1.19

Func (*uintptr) swap ¶ added in go1.19, type value ¶ added in go1.4.

A Value provides an atomic load and store of a consistently typed value. The zero value for a Value returns nil from Value.Load . Once Value.Store has been called, a Value must not be copied.

A Value must not be copied after first use.

The following example shows how to use Value for periodic program config updates and propagation of the changes to worker goroutines.

The following example shows how to maintain a scalable frequently read, but infrequently updated data structure using copy-on-write idiom.

func (*Value) CompareAndSwap ¶ added in go1.17

CompareAndSwap executes the compare-and-swap operation for the Value .

All calls to CompareAndSwap for a given Value must use values of the same concrete type. CompareAndSwap of an inconsistent type panics, as does CompareAndSwap(old, nil).

func (*Value) Load ¶ added in go1.4

Load returns the value set by the most recent Store. It returns nil if there has been no call to Store for this Value.

func (*Value) Store ¶ added in go1.4

Store sets the value of the Value v to val. All calls to Store for a given Value must use values of the same concrete type. Store of an inconsistent type panics, as does Store(nil).

func (*Value) Swap ¶ added in go1.17

Swap stores new into Value and returns the previous value. It returns nil if the Value is empty.

All calls to Swap for a given Value must use values of the same concrete type. Swap of an inconsistent type panics, as does Swap(nil).

On 386, the 64-bit functions use instructions unavailable before the Pentium MMX.

On non-Linux ARM, the 64-bit functions use instructions unavailable before the ARMv6k core.

On ARM, 386, and 32-bit MIPS, it is the caller's responsibility to arrange for 64-bit alignment of 64-bit words accessed atomically via the primitive atomic functions (types Int64 and Uint64 are automatically aligned). The first word in an allocated struct, array, or slice; in a global variable; or in a local variable (because the subject of all atomic operations will escape to the heap) can be relied upon to be 64-bit aligned.

Source Files ¶

Keyboard shortcuts.

: This menu
: Search site
or : Jump to
or : Canonical URL

Golang Libraries, Apps, Golang Jobs and Go Tutorials

Golang News, Tutorials, Go Libraries and Golang Jobs

  • Golang Jobs / Go Developer Jobs
  • Go/JS Full Stack Development

How to use Atomic Pointers in Golang 1.19

“Atomic” in computer programming refers to performing operations one at a time. Objective-C has atomic properties. It ensures a safe reading and writing to a property from different threads. In Objective-C, it is used with immutable types. This is because immutable types are really “recreated” to change it. In other words, changing an immutable type in your code will not cause the compiler to throw an error. However, it’ll instantiate a new object when you do so. A prime example is Go’s append function, it makes a new array for each invocation. In Obj-C, atomic properties will ensure operations are performed one after another to prevent threads from accessing a memory address simultaneously. Since Go is multithreaded, it supports atomic operations as well. Golang 1.19 introduces new atomic types. My favorite addition is  atomic.Pointer  , it provides a sleek alternative to  atomic.Value  . It’s also a great showcase of how generics enhance the developer experience.

The Go 1.19 atomic.Pointer

atomic.Pointer  is a generic type. Unlike  Value  , it does not require asserting your stored value to access it. Here is a code block that defines and stores a pointer :

I instantiate variable  p as a struct literal. I then proceed to store the pointer of the variable s in p , s represents a server connection. Voila, we’ve passed the first step toward atomicity. By storing the variable as an atomic value, we’ll ensure that there is no simultaneous access to the memory address. For example, maps will cause a program to panic if it is read and written simultaneously. As are atomic operations, locks are a great way to prevent these panics.

Golang Atomic Pointer use cases

Golang Libraries, Apps, Golang Jobs and Go Tutorials 2024 . Powered by WordPress

Atomic Operations Provided in The sync/atomic Standard Package

Atomic operations are more primitive than other synchronization techniques. They are lockless and generally implemented directly at hardware level. In fact, they are often used in implementing other synchronization techniques.

Please note, many examples below are not concurrent programs. They are just for demonstration and explanation purposes, to show how to use the atomic functions provided in the sync/atomic standard package.

Overview of Atomic Operations Provided Before Go 1.19-

There is not an AddPointer function for pointers, as Go (safe) pointers don't support arithmetic operations.

Overview of New Atomic Operations Provided Since Go 1.19

Go 1.19 introduced several types, each of which owns a set of atomic operation methods, to achieve the same effects made by the package-level functions listed in the last section.

Among these types, Int32 , Int64 , Uint32 , Uint64 and Uintptr are for integer atomic operations. The methods of the atomic.Int32 type are listed below. The methods of the other four types present in the similar way.

Since Go 1.18, Go has already supported custom generics. And some standard packages started to adopt custom generics since Go 1.19. The sync/atomic package is one of these packages. The Pointer[T any] type introudced in this package by Go 1.19 is a generic type. Its methods are listed below.

Go 1.19 also introduced a Bool type to do boolean atomic operations.

Atomic Operations for Integers

The remaining of this article shows some examples on how to use the atomic operations provided in Go.

If the statement atomic.AddInt32(&n, 1) is replaced with n++ , then the output might be not 1000 .

  • For an unsigned variable v of type T , -v is legal in Go. So we can just pass -v as the second argument of an AddT call.
  • For a positive constant integer c , -c is illegal to be used as the second argument of an AddT call (where T denotes an unsigned integer type). We can used ^T(c-1) as the second argument instead.

This ^T(v-1) trick also works for an unsigned variable v , but ^T(v-1) is less efficient than T(-v) .

In the trick ^T(c-1) , if c is a typed value and its type is exactly T , then the form can shortened as ^(c-1) .

A SwapT function call is like a StoreT function call, but returns the old value.

A CompareAndSwapT function call only applies the store operation when the current value matches the passed old value. The bool return result of the CompareAndSwapT function call indicates whether or not the store operation is applied.

Please note, up to now (Go 1.22), atomic operations for 64-bit words, a.k.a. int64 and uint64 values, require the 64-bit words must be 8-byte aligned in memory. For Go 1.19 introduced atomic method operations, this requirement is always satisfied, either on 32-bit or 64-bit architectures, but this is not true for atomic function operations on 32-bit architectures. Please read memory layout for details.

Atomic Operations for Pointers

Above has mentioned that there are four functions provided in the sync/atomic standard package to do atomic pointer operations, with the help of unsafe pointers.

From the article type-unsafe pointers , we learn that, in Go, values of any pointer type can be explicitly converted to unsafe.Pointer , and vice versa. So values of *unsafe.Pointer type can also be explicitly converted to unsafe.Pointer , and vice versa.

Yes, it is quite verbose to use the pointer atomic functions. In fact, not only are the uses verbose, they are also not protected by Go 1 compatibility guidelines , for these uses require to import the unsafe standard package.

Personally, I think the possibility is small that the legal pointer value atomic operations used in the above example will become illegal later. Even if they become illegal later, the go fix command provided in Go Toolchain should fix them with a later alternative new legal way. But, this is just my opinion, which is not authoritative.

If you do worry about the future legality of the pointer atomic operations used in the above example, you can use the atomic operations introduced in the next section for pointers, though the to be introduced operations are less efficient than the ones introduced in the current section.

On the contrary, the code will be much simpler and cleaner if we use the Go 1.19 introduced generic Pointer type and its methods to do atomic pointer operations, as the following code shows.

More importantly, the implementation using the generic Pointer type is protected by Go 1 compatibility guidelines.

Atomic Operations for Values of Arbitrary Types

The Value type provided in the sync/atomic standard package can be used to atomically load and store values of any type.

Type *Value has several methods: Load , Store , Swap and CompareAndSwap (The latter two are introduced in Go 1.17). The input parameter types of these methods are all interface{} . So any value may be passed to the calls to these methods. But for an addressable Value value v , once the v.Store() (a shorthand of (&v).Store() ) call has ever been called, then the subsequent method calls on value v must also take argument values with the same concrete type as the argument of the first v.Store() call, otherwise, panics will occur. A nil interface argument will also make the v.Store() call panic.

In fact, we can also use the atomic pointer functions explained in the last section to do atomic operations for values of any type, with one more level indirection. Both ways have their respective advantages and disadvantages. Which way should be used depends on the requirements in practice.

Memory Order Guarantee Made by Atomic Operations in Go

Please read Go memory model for details.

The Go 101 project is hosted on Github . Welcome to improve Go 101 articles by submitting corrections for all kinds of mistakes, such as typos, grammar errors, wording inaccuracies, description flaws, code bugs and broken links.

If you would like to learn some Go details and facts every serveral days, please follow Go 101's official Twitter account @zigo_101 .

  • Leanpub store , $19.99+ (You can get this book from this boundle which also contains 3 other books, with the same price) .
  • Amazon Kindle store, (unavailable currently) .
  • Apple Books store , $19.99 .
  • Google Play store , $19.99 .
  • Free ebooks , including pdf, epub and azw3 formats.
  • Color Infection (★★★★★), a physics based original casual puzzle game. 140+ levels.
  • Rectangle Pushers (★★★★★), an original casual puzzle game. Two modes, 104+ levels.
  • Let's Play With Particles , a casual action original game. Three mini games are included.
  • About Go 101 - why this book is written.
  • Acknowledgments
  • An Introduction of Go - why Go is worth learning.
  • The Go Toolchain - how to compile and run Go programs.
  • Introduction of Source Code Elements
  • Keywords and Identifiers
  • Basic Types and Their Value Literals
  • Constants and Variables - also introduces untyped values and type deductions.
  • Common Operators - also introduces more type deduction rules.
  • Function Declarations and Calls
  • Code Packages and Package Imports
  • Expressions, Statements and Simple Statements
  • Basic Control Flows
  • Goroutines, Deferred Function Calls and Panic/Recover
  • Go Type System Overview - a must read to master Go programming.
  • Value Parts - to gain a deeper understanding into Go values.
  • Arrays, Slices and Maps - first-class citizen container types.
  • Functions - function types and values, including variadic functions.
  • Channels - the Go way to do concurrency synchronizations.
  • Interfaces - value boxes used to do reflection and polymorphism.
  • Type Embedding - type extension in the Go way.
  • Type-Unsafe Pointers
  • Generics - use and read composite types
  • Reflections - the reflect standard package.
  • Line Break Rules
  • More About Deferred Function Calls
  • Some Panic/Recover Use Cases
  • Explain Panic/Recover Mechanism in Detail - also explains exiting phases of function calls.
  • Code Blocks and Identifier Scopes
  • Expression Evaluation Orders
  • Value Copy Costs in Go
  • Bounds Check Elimination
  • Concurrency Synchronization Overview
  • Channel Use Cases
  • How to Gracefully Close Channels
  • Other Concurrency Synchronization Techniques - the sync standard package.
  • Atomic Operations - the sync/atomic standard package.
  • Memory Order Guarantees in Go
  • Common Concurrent Programming Mistakes
  • Memory Blocks
  • Memory Layouts
  • Memory Leaking Scenarios
  • Some Simple Summaries
  • Value Conversion, Assignment and Comparison Rules
  • Syntax/Semantics Exceptions
  • Go Details 101
  • Go Tips 101
  • More Go Related Topics

Atomic Operations in Golang – atomic package

Atomic operations are those which are implemented at the hardware level. Go has the atomic package which helps to achieve synchronization when doing concurrency. In this post, we will see what the atomic package has to offer.

What is an atomic operation?

If we do an operation like increment or decrement using channels on a single shared variable, the goroutines will not be synchronized and will produce erroneous output. The atomic operations, on the other hand, are implemented at the hardware level. That means when we create a shared atomic variable and use multiple goroutines to update its value it will be updated correctly.

Importing Golang atomic package

To use the atomic functions we need to import the sync/atomic package.

Atomic functions in Golang

The package contains load, store and the addition operation for the int32, int 64, uint32, uint64, etc. Since only ints are such primitive that can be correctly synchronized using atomics.

Let’s see an example of what can happen if we don’t use atomic.

Go Non Atomic

As can be seen each time the program is run it will produce the wrong output. It happens due to the fact the goroutines accessing and changing the value is not synchronized. So, the changed values are arbitrary and will result in the wrong number of operations.

Now, we convert the code above to synchronized code using atomic.

Now, each time we run it, it will produce the correct output. Since the atomic operations are synchronized it will return the correct output no matter what.

Go Atomic Operation

Use of atomic operations in Golang

Atomic operations are used when we need to have a shared variable between different goroutines which will be updated by them. If the updating operation is not synchronized then it will create a problem that we saw.

Atomic operations solve that problem by synchronizing access to the shared variable and making the output correct.

Go by Example : Atomic Counters

The primary mechanism for managing state in Go is communication over channels. We saw this for example with . There are a few other options for managing state though. Here we’ll look at using the package for accessed by multiple goroutines.

main
( "fmt" "sync" "sync/atomic" )
main() {

We’ll use an atomic integer type to represent our (always-positive) counter.

ops atomic.Uint64

A WaitGroup will help us wait for all goroutines to finish their work.

wg sync.WaitGroup

We’ll start 50 goroutines that each increment the counter exactly 1000 times.

i := 0; i < 50; i++ { wg.Add(1)
func() { for c := 0; c < 1000; c++ {

To atomically increment the counter we use .

.Add(1) }
.Done() }() }

Wait until all the goroutines are done.

.Wait()

Here no goroutines are writing to ‘ops’, but using it’s safe to atomically read a value even while other goroutines are (atomically) updating it.

.Println("ops:", ops.Load()) }

We expect to get exactly 50,000 operations. Had we used a non-atomic integer and incremented it with , we’d likely get a different number, changing between runs, because the goroutines would interfere with each other. Moreover, we’d get data race failures when running with the flag.

go run atomic-counters.go ops: 50000

Next we’ll look at mutexes, another tool for managing state.

Next example: Mutexes .

by Mark McGranaghan and Eli Bendersky | source | license

A question about the atomic operations in golang

Is the size of a pointer value 32 bits or 64 bits in golang when build with GOARCH=amd64 option specified and running on 64-bit OS? If it’s 64-bit size, is a global pointer value 8-byte aligned in memory so that a read or write operation of that pointer value is carried out atomically? For example, in the following code, is it possible that the global pointer p is only partially updated when the read goroutine read the pointer?

The scenario I’m concerning is that there is only one write but multiple reads on a global pointer value, and reading of an old value of the pointer is not important. Thanks in advance!

For example, in the following code, is it possible that the global pointer p is only partially updated when the read goroutine read the pointer?

tl;dr; only using sync/atomic works, if you want something to be atomic. And use race detector on your code, it will point out mistakes.

It’s not just about being atomic, it’s also about the compiler knowing that you meant that operation to be atomic. Also it’s been discussed multiple times on forums.

https://software.intel.com/en-us/blogs/2013/01/06/benign-data-races-what-could-possibly-go-wrong

Hey @ncubrian , as @Egon , has stated, you should be using sync/atomic for atomic operations.

Here is the index of the functions in the sync/atomic package, atomic package - sync/atomic - Go Packages .

P.S. Just for the record, a pointer should only be 8 bits for amd64 , not 32 or 64, but you can always check the size of a type or variable by using the unsafe.Sizeof function if it’s ever important to what you’re doing ( unsafe package - unsafe - Go Packages ).

:stuck_out_tongue:

Thanks for your reply, but I don’t quite understand this. Isn’t a pointer type is as large as an int? Since an int is 32 bits, how come a pointer would be 8 bits?

An int is only 8 bits as well on my 64 bit machine:

If you run that on your computer you should see the size of an integer for the system you’re running the code on.

Edit: That’s wrong, I forgot that unsafe.Sizeof returns the size in bytes , not bits , thought I made a mistake, so you are actually right, depending on the size of the int, but in my case you were right that the pointer was actually 64 bits.

If the address is properly aligned, the value will be written to memory atomically

In this code there is no race because the go statement occurs after assignment to p . If that assignment occurred after the go statement, that would be a data race.

Please also read my caution about data races and undefined behaviour in my reply to your question here, Redirecting to Google Groups

This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.

Ensuring Concurrency Safety with Atomic Operations in Golang

Table of contents.

In many backend services, configuration files or dictionary data need to be loaded dynamically. So when accessing these configurations or dictionaries, it is necessary to add locks to these data to ensure the security of concurrent reads and writes. Normally, read and write locks are required. Here’s an example of a read/write lock.

Read/Write Locks to Load Data

Using read/write locks ensures that access to data does not result in a race to state.

Config struct { sync.RWMutex data map[string]interface{} } func (c *Config) Load() { c.Lock() defer c.Unlock() c.data = c.load() } func (c *Config) load() map[string]interface{} { // 数据的加载 return make(map[string]interface{}) } func (c *Config) Get() map[string]interface{} { c.RLock() defer c.RUnlock() return c.data }

Dynamic data replacement using atomic operations

One characteristic of this type of business requirement is that reads are very frequent, but updates to the data will be relatively infrequent. We can replace the read and write locks with the following method.

"sync/atomic" import "unsafe" type Config struct { data unsafe.Pointer } func (c *Config) Load() { v := c.load() atomic.StorePointer(&c.data, unsafe.Pointer(&v)) } func (c *Config) load() map[string]interface{} { // Loading of data return make(map[string]interface{}) } func (c *Config) Get() map[string]interface{} { v := atomic.LoadPointer(&c.data) return *(*map[string]interface{})(v) }

Using atomic operations ensures that when concurrent reads and writes are performed, the new map is not acquired by the previous read operation when the data is updated, thus ensuring concurrent security.

Performance Test

Here is a performance test where ConfigV2 is using atomic operations to replace the data of map.

BenchmarkConfig(b *testing.B) { config := &Config{} go func() { for range time.Tick(time.Second) { config.Load() } }() config.Load() b.ResetTimer() for i := 0; i < b.N; i++ { _ = config.Get() } } func BenchmarkConfigV2(b *testing.B) { config := &ConfigV2{} go func() { for range time.Tick(time.Second) { config.Load() } }() config.Load() b.ResetTimer() for i := 0; i < b.N; i++ { _ = config.Get() } }

The difference between the two is 40 times, and the results are as follows:

goarch: amd64 pkg: lpflpf/loaddata cpu: Intel(R) Xeon(R) CPU E5-2630 v3 @ 2.40GHz BenchmarkConfig-32 551491118 21.79 ns/op 0 B/op 0 allocs/op BenchmarkConfigV2-32 1000000000 0.5858 ns/op 0 B/op 0 allocs/op PASS ok lpflpf/loaddata 14.870s
  • In some kinds of business where there are many reads and few writes, atomic operations can be used instead of read/write locks to ensure concurrency security.
  • The reason for the higher performance of atomic operations may be: read-write locks require one more atomic operation to be added. (To be verified)

Get the Reddit app

Ask questions and post articles about the Go programming language and related tools, events etc.

Atomic variable assignment

According to the Go memory model -

To serialize access, protect the data with channel operations or other synchronization primitives such as those in the sync and sync/atomic packages.

However it also states -

Otherwise, a read r of a memory location x that is not larger than a machine word must observe some write w such that r does not happen before w and there is no write w' such that w happens before w' and w' happens before r. That is, each read must observe a value written by a preceding or concurrent write.

I see pointer assignment from multiple goroutines detected as data races.

Isn't pointer assignment a word size operation? (or any other assignment to types smaller than a word) If so, why do we need synchronization? why the race detector detect those as races?

By continuing, you agree to our User Agreement and acknowledge that you understand the Privacy Policy .

Enter the 6-digit code from your authenticator app

You’ve set up two-factor authentication for this account.

Enter a 6-digit backup code

Create your username and password.

Reddit is anonymous, so your username is what you’ll go by here. Choose wisely—because once you get a name, you can’t change it.

Reset your password

Enter your email address or username and we’ll send you a link to reset your password

Check your inbox

An email with a link to reset your password was sent to the email address associated with your account

Choose a Reddit account to continue

  • Data Types in Go
  • Go Keywords
  • Go Control Flow
  • Go Functions
  • GoLang Structures
  • GoLang Arrays
  • GoLang Strings
  • GoLang Pointers
  • GoLang Interface
  • GoLang Concurrency

atomic.StorePointer() Function in Golang With Examples

In Go language, atomic packages supply lower-level atomic memory that is helpful is implementing synchronization algorithms. The StorePointer() function in Go language is used to atomically store val into *addr . This function is defined under the atomic package. Here, you need to import the “sync/atomic” package in order to use these functions.

Here, addr indicates address.

Note: (*unsafe.Pointer) is the pointer to a unsafe.Pointer value. And unsafe.Pointer type is helpful in enabling transitions between arbitrary types and builtin uintptr type. Moreover, unsafe is a package that is helpful in type safety of Go programs.

Return Value: It stores the val into *addr and then can be returned when required.

                 

Here, the value unsafe.Pointer is stored in *addr that’s why above code returns the stated output.

                 

Here, the stated unsafe.Pointer val is stored and the address of the stored val is returned here. Moreover, the address can be different at different run times.

author

Please Login to comment...

Similar reads.

  • Go Language
  • GoLang-atomic

Improve your Coding Skills with Practice

 alt=

What kind of Experience do you want to share?

  • Stack Overflow for Teams Where developers & technologists share private knowledge with coworkers
  • Advertising & Talent Reach devs & technologists worldwide about your product, service or employer brand
  • OverflowAI GenAI features for Teams
  • OverflowAPI Train & fine-tune LLMs
  • Labs The future of collective knowledge sharing
  • About the company Visit the blog

Collectives™ on Stack Overflow

Find centralized, trusted content and collaborate around the technologies you use most.

Q&A for work

Connect and share knowledge within a single location that is structured and easy to search.

Get early access and see previews of new features.

Golang: Assigning a value to struct member that is a pointer

I'm trying to assign a value to a struct member that is a pointer, but it gives "panic: runtime error: invalid memory address or nil pointer dereference" at runtime...

The runtime error seems to come from the assignment of the value with *strctTest.blTest = false , but why? How do I set it to false?

Bart Silverstrim's user avatar

  • Here is a nice explanation of pointers in Go: dave.cheney.net/2017/04/26/… –  fhe Commented May 5, 2017 at 19:01

4 Answers 4

Why is it an error? Because a pointer only points. It doesn't create anything to point AT . You need to do that.

How to set it to false? This all depends on WHY you made it a pointer.

Is every copy of this supposed to point to the same bool? Then it should be allocated some space in a creation function.

Is the user supposed to point it at a boolean of his own? Then it should be set manually when creating the object.

Zan Lynx's user avatar

  • My attempt to try the first method gave a compiler error ("invalid pointer type *bool for composite literal") but the second method worked for my purposes. Thank you! –  Bart Silverstrim Commented May 5, 2017 at 20:14
  • @BartSilverstrim Ah well I didn't test it. I guess I should have. –  Zan Lynx Commented May 6, 2017 at 2:29
  • @BartSilverstrim I fixed my first example. –  Zan Lynx Commented May 6, 2017 at 2:42

You could also do something like:

https://play.golang.org/p/OWSosQhrUql

Andrei Lupuleasa's user avatar

  • this is exactly what I was looking for .. Thanks :) –  Prashant Commented Jul 18 at 7:39

Another way you can think of it is the zero value of a boolean is false.

This is not as clear but another way to do it.

https://play.golang.org/p/REbnJumcFi

I would recommend a New() func that returns a reference to a initialized struct type.

JT.'s user avatar

  • 1 This didn't really answer the OP's question. He asked how to assign a value to a bool, not how to make a new memory allocation. In your example you should add how to assign a value to it. See play.golang.org/p/iqOD5hLcPPp –  nosequeldeebee Commented May 22, 2018 at 3:07
  • If you're using a bool pointer instead of a bool, it's hopefully because you want to support three values true/false/nil, not 2 with default. –  scosman Commented Aug 15 at 17:38

Following up on JTs Answer, I also would recommend using the new function as such:

After initializing the memory with new() , you can directly assign a value to the de-referenced pointer. This way you do not need to use another variable to get the address from.

https://go.dev/play/p/BmekoTalQVh

Alexander Köb's user avatar

Your Answer

Reminder: Answers generated by artificial intelligence tools are not allowed on Stack Overflow. Learn more

Sign up or log in

Post as a guest.

Required, but never shown

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy .

Not the answer you're looking for? Browse other questions tagged pointers go struct or ask your own question .

  • The Overflow Blog
  • Battling ticket bots and untangling taxes at the frontiers of e-commerce
  • Ryan Dahl explains why Deno had to evolve with version 2.0
  • Featured on Meta
  • We've made changes to our Terms of Service & Privacy Policy - July 2024
  • Bringing clarity to status tag usage on meta sites
  • Feedback requested: How do you use tag hover descriptions for curating and do...

Hot Network Questions

  • Gauss and recursion – would defining factorial recursively have been quite surprising to him?
  • What if something goes wrong during the seven minutes of terror?
  • How can flyby missions work?
  • 'best poster' and 'best talk' prizes - can we do better determining winners?
  • Why would an incumbent politician or party need to be re-elected to fulfill a campaign promise?
  • Momentary solo circuit
  • Print lines between two patterns where first pattern appears more than once before second pattern
  • Cryptic crossword: London calling
  • How many people could we get off of the planet in a month?
  • Is the Garmin Edge 530 still a good choice for a beginner in 2024?
  • Is there a grammatical term for the ways in which 'to be' is used in these sentences?
  • Does a cube under high pressure transform into a ball?
  • How old were Phineas and Ferb? What year was it?
  • Why is Ganondorf in LOZ Windwaker?
  • Did the French janitor at the University of Hanoi receive a higher base pay than a Vietnamese professor?
  • Arranging people in a jeep.
  • Why do only 2 USB cameras work while 4 USB cameras cannot stream at once?
  • What did Scott Lang mean by "living as a tenant of the state"?
  • Did anyone ever ask Neil Armstrong whether he said "for man" or "for a man?"
  • How can I understand op-amp operation modes?
  • Can there be clouds of free electrons in space?
  • Are "lie low" and "keep a low profile" interchangeable?
  • Finite loop runs infinitely
  • Which BASIC dialect first featured a single-character comment introducer?

is pointer assignment atomic in golang

IMAGES

  1. How to use Atomic Pointers in Golang 1.19

    is pointer assignment atomic in golang

  2. Playing with Pointers in Golang

    is pointer assignment atomic in golang

  3. GoLang Tutorial

    is pointer assignment atomic in golang

  4. GoLang Tutorial

    is pointer assignment atomic in golang

  5. Atomic pointer in Go 1.19 and dependency injection

    is pointer assignment atomic in golang

  6. Golang Atomic

    is pointer assignment atomic in golang

COMMENTS

  1. Is assigning a pointer atomic in Go?

    The answer to the former, as of right now is yes, assigning (loading/storing) a pointer is atomic in Golang, this lies in the updated Go memory model. Otherwise, a read r of a memory location x that is not larger than a machine word must observe some write w such that r does not happen before w and there is no write w' such that w happens ...

  2. Is variable assignment atomic in go?

    3. Assignment is not atomic, which is implied by the first sentence in the quoted documentation, and reinforced through the document as the conditions on observability are described. If that is unsatisfactory, I suggest you raise an issue with the go project for clarification in the documentation. - JimB.

  3. Atomic Pointers in Go 1.19

    In Obj-C, atomic properties will ensure operations are performed one after another, to prevent threads from accessing a memory address at the same time. Since Go is multithreaded, it supports atomic operations as well. Go 1.19 introduces new atomic types. My favorite addition is atomic.Pointer , it provides a sleek alternative to atomic.Value .

  4. Atomic Operations in Go: Lockless techniques for managing state and

    Go provides a package named sync/atomic that includes a set of functions for performing atomic operations on primitive data types, such as integers and pointers.

  5. Is assigning a pointer atomic in go · Issue #38667 · golang/go

    More generally, pointer assignment is atomic, but you need more than that to make an example like yours work. The Go project does not use the issue tracker for questions.

  6. atomic package

    Package atomic provides low-level atomic memory primitives for sync operations in Go. Learn how to use them safely and efficiently.

  7. The Go 1.19 Atomic Wrappers and why to use them

    Here's a short blog on Go's (1.19+) sync/atomic additions to the library and why you'd want to use them. This article will assume that you…

  8. How to use Atomic Pointers in Golang 1.19

    In Obj-C, atomic properties will ensure operations are performed one after another to prevent threads from accessing a memory address simultaneously. Since Go is multithreaded, it supports atomic operations as well. Golang 1.19 introduces new atomic types. My favorite addition is atomic.Pointer , it provides a sleek alternative to atomic.Value .

  9. Atomic Operations Provided in The sync/atomic Standard Package

    Above has mentioned that there are four functions provided in the sync/atomic standard package to do atomic pointer operations, with the help of unsafe pointers. From the article type-unsafe pointers, we learn that, in Go, values of any pointer type can be explicitly converted to unsafe.Pointer, and vice versa.

  10. Atomic Operations in Golang

    Atomic operations are those which are implemented at the hardware level. Go has the atomic package which helps to achieve synchronization when doing concurrency. In this post, we will see what the atomic package has to offer.

  11. Go by Example: Atomic Counters

    We saw this for example with worker pools. There are a few other options for managing state though. Here we'll look at using the sync/atomic package for atomic counters accessed by multiple goroutines. package main. import ( "fmt" "sync" "sync/atomic" ) func main() {. We'll use an atomic integer type to represent our (always-positive) counter.

  12. Is assigning a map atomic in go

    Hi, @SmallSmartMouse, No, map assignment is not atomic. Also, your reassignment of the global data map with the temp one you created is not atomic. If your idea is to initialize a map and then store it into a global variable where it will be considered read-only, you can do that with the sync/atomic package and some pointer hackery: https ...

  13. A question about the atomic operations in golang

    Hey @ncubrian, as @Egon, has stated, you should be using sync/atomic for atomic operations. Here is the index of the functions in the sync/atomic package, atomic package - sync/atomic - Go Packages. P.S. Just for the record, a pointer should only be 8 bits for amd64, not 32 or 64, but you can always check the size of a type or variable by using ...

  14. Ensuring Concurrency Safety with Atomic Operations in Golang

    In some kinds of business where there are many reads and few writes, atomic operations can be used instead of read/write locks to ensure concurrency security. The reason for the higher performance of atomic operations may be: read-write locks require one more atomic operation to be added. (To be verified) golang.

  15. The benefits of Atomic Pointers in Go 1.19 : r/golang

    Good to have this feature in Go! Btw, Does anybody see a reason to use atomic.Pointer when dealing with primitive types?

  16. Why does 'atomic' use unsafe pointers? : r/golang

    Why does 'atomic' use unsafe pointers? As far as I know the two ways of updating a pointer without data races is by using a muted lock or by using the atomic package. Locks create contention so if we can avoid it, sounds good. But the atomic package requires that your pointer be an unsafe pointer to operate on it. To me this is a major downside.

  17. Atomic variable assignment : r/golang

    Isn't pointer assignment a word size operation? (or any other assignment to types smaller than a word) If so, why do we need synchronization? why the race detector detect those as races?

  18. atomic.StorePointer() Function in Golang With Examples

    The StorePointer () function in Go language is used to atomically store val into *addr. This function is defined under the atomic package. Here, you need to import the "sync/atomic" package in order to use these functions. Syntax: Here, addr indicates address. Note: (*unsafe.Pointer) is the pointer to a unsafe.Pointer value.

  19. How to use Load and Store of atomic in golang

    Here are the piece of code to test the mutual access of write and read of a struct B using atomic.Value, but I've got some error indicating invalid pointer access. So ...

  20. Golang: Assigning a value to struct member that is a pointer

    16 I'm trying to assign a value to a struct member that is a pointer, but it gives "panic: runtime error: invalid memory address or nil pointer dereference" at runtime...