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 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 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) CompareAndSwap(old, new int32) (swapped bool)
  • func (x *Int32) Load() 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) CompareAndSwap(old, new int64) (swapped bool)
  • func (x *Int64) Load() 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) CompareAndSwap(old, new uint32) (swapped bool)
  • func (x *Uint32) Load() 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) CompareAndSwap(old, new uint64) (swapped bool)
  • func (x *Uint64) Load() 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) CompareAndSwap(old, new uintptr) (swapped bool)
  • func (x *Uintptr) Load() 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 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 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) CompareAndSwap ¶ added in go1.19

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

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

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) compareandswap ¶ added in go1.19, func (*int64) load ¶ added in go1.19, 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) compareandswap ¶ added in go1.19, func (*uint32) load ¶ added in go1.19, 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) compareandswap ¶ added in go1.19, func (*uint64) load ¶ added in go1.19, 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) compareandswap ¶ added in go1.19, func (*uintptr) load ¶ added in go1.19, 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 Load. Once 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.

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

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

@randall77

randall77 commented Apr 26, 2020

Sorry, something went wrong.

@randall77

SmallSmartMouse commented Apr 29, 2020

@lsytj0413

lsytj0413 commented Apr 29, 2020

@ianlancetaylor

ianlancetaylor commented Apr 30, 2020

@smallnest

No branches or pull requests

@ianlancetaylor

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 @go100and1 .

  • 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

Package atomic

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".

Package files

doc.go value.go

func AddInt32 ¶

AddInt32 atomically adds delta to *addr and returns the new value.

func AddInt64 ¶

AddInt64 atomically adds delta to *addr and returns the new value.

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)).

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)).

func AddUintptr ¶

AddUintptr atomically adds delta to *addr and returns the new value.

func CompareAndSwapInt32 ¶

CompareAndSwapInt32 executes the compare-and-swap operation for an int32 value.

func CompareAndSwapInt64 ¶

CompareAndSwapInt64 executes the compare-and-swap operation for an int64 value.

func CompareAndSwapPointer ¶

CompareAndSwapPointer executes the compare-and-swap operation for a unsafe.Pointer value.

func CompareAndSwapUint32 ¶

CompareAndSwapUint32 executes the compare-and-swap operation for a uint32 value.

func CompareAndSwapUint64 ¶

CompareAndSwapUint64 executes the compare-and-swap operation for a uint64 value.

func CompareAndSwapUintptr ¶

CompareAndSwapUintptr executes the compare-and-swap operation for a uintptr value.

func LoadInt32 ¶

LoadInt32 atomically loads *addr.

func LoadInt64 ¶

LoadInt64 atomically loads *addr.

func LoadPointer ¶

LoadPointer atomically loads *addr.

func LoadUint32 ¶

LoadUint32 atomically loads *addr.

func LoadUint64 ¶

LoadUint64 atomically loads *addr.

func LoadUintptr ¶

LoadUintptr atomically loads *addr.

func StoreInt32 ¶

StoreInt32 atomically stores val into *addr.

func StoreInt64 ¶

StoreInt64 atomically stores val into *addr.

func StorePointer ¶

StorePointer atomically stores val into *addr.

func StoreUint32 ¶

StoreUint32 atomically stores val into *addr.

func StoreUint64 ¶

StoreUint64 atomically stores val into *addr.

func StoreUintptr ¶

StoreUintptr atomically stores val into *addr.

func SwapInt32 ¶ 1.2

SwapInt32 atomically stores new into *addr and returns the previous *addr value.

func SwapInt64 ¶ 1.2

SwapInt64 atomically stores new into *addr and returns the previous *addr value.

func SwapPointer ¶ 1.2

SwapPointer atomically stores new into *addr and returns the previous *addr value.

func SwapUint32 ¶ 1.2

SwapUint32 atomically stores new into *addr and returns the previous *addr value.

func SwapUint64 ¶ 1.2

SwapUint64 atomically stores new into *addr and returns the previous *addr value.

func SwapUintptr ¶ 1.2

SwapUintptr atomically stores new into *addr and returns the previous *addr value.

type Value ¶ 1.4

A Value provides an atomic load and store of a consistently typed value. The zero value for a Value returns nil from Load. Once 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 ¶ 1.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 ¶ 1.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 ¶ 1.4

Store sets the value of the Value to x. 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 ¶ 1.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. The first word in a variable or in an allocated struct, array, or slice can be relied upon to be 64-bit aligned.

go-language.org

Documentation License: Creative Commons Attribution 3.0 License | Code License: BSD-3-Clause

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.

An Introduction to Go's `sync/atomic` Package: Atomic Operations

What is the `sync/atomic` package.

The `sync/atomic` package in Go is designed to provide low-level atomic operations for managing concurrent access to shared variables. These atomic operations include addition, subtraction, multiplication, and bitwise operations, such as AND, OR, and XOR. Atomic operations are performed in a single step, which prevents other threads or goroutines from interfering with the operation in progress. This ensures that the operation is completed without being interrupted or causing data races.

Some of the most common atomic operations in the `sync/atomic` package include:

  • `AddInt32`, `AddInt64`: Add an integer value to a variable atomically.
  • `CompareAndSwapInt32`, `CompareAndSwapInt64`: Perform a compare-and-swap operation on an integer variable atomically.
  • `LoadInt32`, `LoadInt64`: Load the value of an integer variable atomically.
  • `StoreInt32`, `StoreInt64`: Store a new value in an integer variable atomically.
  • `SwapInt32`, `SwapInt64`: Swap the value of an integer variable with a new value atomically.

Before diving into the examples, let's understand the basics of atomic operations and why they are useful in concurrent programming.

Why are atomic operations useful in concurrent programming?

In concurrent programming, multiple goroutines access and modify shared variables. If two or more goroutines attempt to modify the same variable simultaneously, the final value of the variable may be unpredictable, leading to data races and other synchronization issues. This is where atomic operations come into play.

Atomic operations allow you to perform read, write, or update operations on shared variables in a single, uninterruptible step. This ensures that other goroutines cannot interfere with the operation in progress, eliminating data races and improving the overall performance of concurrent programs.

Now that we have a basic understanding of atomic operations let's look at some examples and code snippets that demonstrate the use of the `sync/atomic` package in Go.

Example 1: Using `sync/atomic` for atomic addition

Let's start with a simple example of using the `sync/atomic` package to perform atomic addition on a shared integer variable. In this example, we'll create two goroutines that increment a shared variable 1000 times each. Without using atomic operations, this could lead to data races and unpredictable results.

In this example, we use the `atomic.AddInt64` function to increment the shared `counter` variable atomically. This ensures that the two goroutines do not interfere with each other's operations, and the final value of the counter is always 2000.

Example 2: Using `sync/atomic` for atomic compare-and-swap

In this example, we'll demonstrate the use of the `sync/atomic` package for performing a compare-and-swap operation on a shared integer variable. We'll create a simple program that increments a shared counter variable until it reaches 100. If the counter is already at 100, the program should not increment it further.

In this example, we use the `atomic.LoadInt32` function to load the current value of the shared `counter` variable atomically. We then use the `atomic.CompareAndSwapInt32` function to compare the current value of the counter with 100 and increment it only if the current value is less than 100. This ensures that the counter is not incremented beyond 100, even when multiple goroutines are trying to increment it concurrently.

The `sync/atomic` package in Go provides a powerful set of atomic operations for managing concurrent access to shared variables. These atomic operations enable safe modification of shared variables without causing data races or other synchronization issues, making them an essential tool for concurrent programming in Go. By using the `sync/atomic` package, you can improve the performance and reliability of your concurrent programs, making them more efficient and easier to maintain.

If you are looking to hire remote Go developers , consider partnering with Reintech. Our team of experienced Go developers can help you build high-performance, concurrent applications using the latest Go technologies and best practices, including the `sync/atomic` package.

If you're interested in enhancing this article or becoming a contributing author, we'd love to hear from you.

Please contact Sasha at [email protected] to discuss the opportunity further or to inquire about adding a direct link to your resource. We welcome your collaboration and contributions!

Atomic operations

Concurrent programming, sync/atomic package.

Hire Expert Remote JavaScript and Go Developers Proficient in Stripe API

Hire Skilled JavaScript and Go Developers with AWS S3 Expertise

Hire Expert Remote JavaScript and Go Developers with React Material Skill

secure.food

Package atomic

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".

Package files

doc.go value.go

func AddInt32 ¶

AddInt32 atomically adds delta to *addr and returns the new value.

func AddInt64 ¶

AddInt64 atomically adds delta to *addr and returns the new value.

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)).

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)).

func AddUintptr ¶

AddUintptr atomically adds delta to *addr and returns the new value.

func CompareAndSwapInt32 ¶

CompareAndSwapInt32 executes the compare-and-swap operation for an int32 value.

func CompareAndSwapInt64 ¶

CompareAndSwapInt64 executes the compare-and-swap operation for an int64 value.

func CompareAndSwapPointer ¶

CompareAndSwapPointer executes the compare-and-swap operation for a unsafe.Pointer value.

func CompareAndSwapUint32 ¶

CompareAndSwapUint32 executes the compare-and-swap operation for a uint32 value.

func CompareAndSwapUint64 ¶

CompareAndSwapUint64 executes the compare-and-swap operation for a uint64 value.

func CompareAndSwapUintptr ¶

CompareAndSwapUintptr executes the compare-and-swap operation for a uintptr value.

func LoadInt32 ¶

LoadInt32 atomically loads *addr.

func LoadInt64 ¶

LoadInt64 atomically loads *addr.

func LoadPointer ¶

LoadPointer atomically loads *addr.

func LoadUint32 ¶

LoadUint32 atomically loads *addr.

func LoadUint64 ¶

LoadUint64 atomically loads *addr.

func LoadUintptr ¶

LoadUintptr atomically loads *addr.

func StoreInt32 ¶

StoreInt32 atomically stores val into *addr.

func StoreInt64 ¶

StoreInt64 atomically stores val into *addr.

func StorePointer ¶

StorePointer atomically stores val into *addr.

func StoreUint32 ¶

StoreUint32 atomically stores val into *addr.

func StoreUint64 ¶

StoreUint64 atomically stores val into *addr.

func StoreUintptr ¶

StoreUintptr atomically stores val into *addr.

func SwapInt32 ¶

SwapInt32 atomically stores new into *addr and returns the previous *addr value.

func SwapInt64 ¶

SwapInt64 atomically stores new into *addr and returns the previous *addr value.

func SwapPointer ¶

SwapPointer atomically stores new into *addr and returns the previous *addr value.

func SwapUint32 ¶

SwapUint32 atomically stores new into *addr and returns the previous *addr value.

func SwapUint64 ¶

SwapUint64 atomically stores new into *addr and returns the previous *addr value.

func SwapUintptr ¶

SwapUintptr atomically stores new into *addr and returns the previous *addr value.

type Value ¶

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

A Value must not be copied after first use.

▹ Example (Config)

▾ Example (Config)

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

▹ Example (ReadMostly)

▾ Example (ReadMostly)

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

func (*Value) Load ¶

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 ¶

Store sets the value of the Value to x. 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).

On x86-32, 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, x86-32, and 32-bit MIPS, it is the caller's responsibility to arrange for 64-bit alignment of 64-bit words accessed atomically. The first word in a variable or in an allocated struct, array, or slice can be relied upon to be 64-bit aligned.

Package atomic

Examples (expand all), package files.

doc.go type.go value.go

func AddInt32 ¶

Func addint64 ¶, func adduint32 ¶, func adduint64 ¶, func adduintptr ¶, func compareandswapint32 ¶, func compareandswapint64 ¶, func compareandswappointer ¶, func compareandswapuint32 ¶, func compareandswapuint64 ¶, func compareandswapuintptr ¶, func loadint32 ¶, func loadint64 ¶, func loadpointer ¶, func loaduint32 ¶, func loaduint64 ¶, func loaduintptr ¶, func storeint32 ¶, func storeint64 ¶, func storepointer ¶, func storeuint32 ¶, func storeuint64 ¶, func storeuintptr ¶, func swapint32 ¶ 1.2, func swapint64 ¶ 1.2, func swappointer ¶ 1.2, func swapuint32 ¶ 1.2, func swapuint64 ¶ 1.2, func swapuintptr ¶ 1.2, type bool ¶ 1.19, func (*bool) compareandswap ¶ 1.19, func (*bool) load ¶ 1.19, func (*bool) store ¶ 1.19, func (*bool) swap ¶ 1.19, type int32 ¶ 1.19, func (*int32) add ¶ 1.19, func (*int32) compareandswap ¶ 1.19, func (*int32) load ¶ 1.19, func (*int32) store ¶ 1.19, func (*int32) swap ¶ 1.19, type int64 ¶ 1.19, func (*int64) add ¶ 1.19, func (*int64) compareandswap ¶ 1.19, func (*int64) load ¶ 1.19, func (*int64) store ¶ 1.19, func (*int64) swap ¶ 1.19, type pointer ¶, func (*pointer[t]) compareandswap ¶, func (*pointer[t]) load ¶, func (*pointer[t]) store ¶, func (*pointer[t]) swap ¶, type uint32 ¶ 1.19, func (*uint32) add ¶ 1.19, func (*uint32) compareandswap ¶ 1.19, func (*uint32) load ¶ 1.19, func (*uint32) store ¶ 1.19, func (*uint32) swap ¶ 1.19, type uint64 ¶ 1.19, func (*uint64) add ¶ 1.19, func (*uint64) compareandswap ¶ 1.19, func (*uint64) load ¶ 1.19, func (*uint64) store ¶ 1.19, func (*uint64) swap ¶ 1.19, type uintptr ¶ 1.19, func (*uintptr) add ¶ 1.19, func (*uintptr) compareandswap ¶ 1.19, func (*uintptr) load ¶ 1.19, func (*uintptr) store ¶ 1.19, func (*uintptr) swap ¶ 1.19, type value ¶ 1.4.

▸ Example (Config)

▾ Example (Config)

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

▸ Example (ReadMostly)

▾ Example (ReadMostly)

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

func (*Value) CompareAndSwap ¶ 1.17

Func (*value) load ¶ 1.4, func (*value) store ¶ 1.4, func (*value) swap ¶ 1.17.

IMAGES

  1. Go Pointers

    go pointer assignment atomic

  2. Atomic pointer in Go 1.19 and dependency injection

    go pointer assignment atomic

  3. C++ : Is pointer assignment atomic in C++?

    go pointer assignment atomic

  4. Go Pointer to Pointer (Double Pointer)

    go pointer assignment atomic

  5. Atomic Theory Timeline Project: A Visual History of the Atom

    go pointer assignment atomic

  6. assignment atomic radius

    go pointer assignment atomic

VIDEO

  1. What are Pointers? How to Use Them? and How they can Improve your C++ Programming Skills

  2. The Pointer Sisters

  3. BARC Assignment Atomic & Molecular Physics @physicsgalaxy1537

  4. Pointers In Go Programming Language

  5. BCHCT 131 solved assignment 2024 // BCHCT 131 solved Assignment 2024-25 // #bchct131 #bchct131_ignou

  6. 02 Short Hand Syntax Issue no-name issue

COMMENTS

  1. Is assigning a pointer atomic in Go?

    The only things which are guaranteed to be atomic in go are the operations in sync.atomic.. So if you want to be certain you'll either need to take a lock, eg sync.Mutex or use one of the atomic primitives. I don't recommend using the atomic primitives though as you'll have to use them everywhere you use the pointer and they are difficult to get right.

  2. atomic package

    The following example shows how to maintain a scalable frequently read, but infrequently updated data structure using copy-on-write idiom. package main import ( "sync" "sync/atomic" ) func main() { type Map map[string]string var m atomic.Value m.Store(make(Map)) var mu sync.Mutex // used only by writers // read function can be used to read the data without further synchronization read := func ...

  3. go

    4. It is a datarace because you have a concurrent memory read/write operation without explicit synchronization. The pointer assignment in the goroutine is concurrent with the pointer read in the main goroutine. The fact that a memory write for a pointer-size value is atomic is not relevant to a memory race.

  4. Is assigning a pointer atomic in go · Issue #38667

    Is assigning a pointer atomic in go #38667. Closed SmallSmartMouse opened this issue Apr 26, 2020 · 4 comments Closed ... 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. Please use a forum for this discussion.

  5. 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.So values of *unsafe.Pointer type can also be explicitly converted to unsafe.Pointer ...

  6. 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 .

  7. atomic

    Overview . 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 ...

  8. Atomic pointer in Go 1.19 and dependency injection

    The sync/atomic.Pointer solves this issue with generics by simple and elegant way. The sync/atomic.Pointer is not a silver bullet to substitute all sync.Mutex locking, but ideal for DI, because it's enough to use the new DI value at the next case. The DI value can be replaced, but the old value reference can be used, because it's a pointer ...

  9. How to use Atomic Pointers in Golang 1.19

    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 : package mainimport ("fmt" "net" "sync/atomic")type ServerConn struct {Connection net.Conn ID string Open bool}func main()

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

    The first sentence on their readme: Simple wrappers for primitive types to enforce atomic access. Fast-forward to Go 1.19 and beyond and a new set of sync/atomic types have been added to the ...

  11. An Introduction to Go's `sync/atomic` Package: Atomic Operations

    The `sync/atomic` package in Go is designed to provide low-level atomic operations for managing concurrent access to shared variables. These atomic operations include addition, subtraction, multiplication, and bitwise operations, such as AND, OR, and XOR. Atomic operations are performed in a single step, which prevents other threads or ...

  12. atomic

    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 ...

  13. Package atomic

    Overview . 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 ...

  14. Mastering Atomic Counters in Go: A Guide to Efficient State Management

    Understanding Atomic Counters. In Go, an atomic counter is a shared variable that multiple goroutines can access concurrently. The term "atomic" refers to the indivisible nature of operations performed on the counter.When a goroutine performs an operation on an atomic counter, it appears as if the operation happens instantly and is not interrupted by other goroutines.

  15. Understanding Golang's Atomic Package and Mutexes

    The sync/atomic package provides low-level atomic memory primitives which can be used to modify values without the fear of race conditions. Key features of the atomic package: Atomic Operations: These functions allow operations on integers and pointers to be performed atomically. For example, atomic.AddInt64 adds an integer to an int64 value ...

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

    Theoretically, the current atomic.SwapPointer (for example) using unsafe.Pointer is more powerful than the type-safe. func SwapPointer[T any](addr **T, new *T) (old *T) That's inherent when adding more type-safety - it's the entire point of making something type-safe. But I would expect that we would have been fine giving up this extra power ...

  17. 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 ...

  18. atomic

    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. The first word in a variable or in an allocated struct, array, or slice can be relied upon to be 64-bit aligned. Go is an open source programming language that makes it easy to build simple, reliable, and ...

  19. - The Go Programming Language

    130 131 // AddUint64 atomically adds delta to *addr and returns the new value. 132 // To subtract a signed positive constant value c from x, do AddUint64(&x, ^uint64(c-1)). 133 // In particular, to decrement x, do AddUint64(&x, ^uint64(0)). 134 // Consider using the more ergonomic and less error-prone [Uint64.Add] instead 135 // (particularly ...

  20. A Brief About Go Atomic

    For atomic operations on variables in Go, the sync/atomic package offers certain low-level methods. In Go, these methods allow several goroutines to securely change a shared variable without using locks or any other explicit synchronization. Functions like AddInt64, AddUint32, CompareAndSwapInt32, etc., for performing elementary arithmetic on ...

  21. Atomic pointers in GO 1.19

    "Atomic", in computer programming, refers to performing operations one at a time. Objective-C has atomic properties, it ensures safe read and writes to a property from different threads. In…