Go Atomic operation

Source: Internet
Author: User
Tags cas
This is a creation in Article, where the information may have evolved or changed.
This article explains the common operations of sync.atomic in Golang

The atomic operation provided by atomic ensures that only one goroutine can operate on the variable at any one time, and the use of atomic avoids a large number of lock operations in the program.

Atomic common operations are:

    • Changes
    • Gta5-In
    • Compare and Exchange
    • Exchange
    • Store

These actions are described separately below.


Increase or decrease operation

The following additions and deletions are provided in the atomic package with the add prefix:

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


It should be noted that the first parameter must be a pointer-type value, and the pointer variable can be used to obtain the address of the operand in memory, thus imposing special CPU instructions to ensure that only one goroutine can operate at the same time.

Examples of Use:

 Package MainImport (    "FMT"    "Sync/atomic"    "Time")func Main() {   var opts Int64 = 0    for I := 0; I <  -; I++ {        //Note the first parameter must be an address       Atomic.AddInt64(&opts, 3) //Garco       //atomic. AddInt64 (&opts,-1) minus Operation        Time.Sleep( Time.Millisecond)   }    Time.Sleep( Time.Second)   FMT.Println("opts:", Atomic.LoadInt64(&opts))}


Loading operations

The atomic package provides the following additions and deletions that are prefixed with the load:

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

The load operation guarantees the value of the read variable of the atom, and when read, no other CPU operation can read and write the variable, and its implementation mechanism is supported by the underlying hardware. See the example above atomic.LoadInt64(&opts) .


Compare and Exchange

This operation is referred to as CAS (Compare and Swap). The prefixes for this type of operation are CompareAndSwap :

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


The operation first ensures that the value of the variable has not been changed before it is exchanged, that is, the value recorded by the parameter is still maintained old , and the exchange operation is performed only if this is true. CAS practice is similar to the optimistic locking mechanism that is common when working with databases.

It is important to note that when there is a large number of goroutine to read and write to the variable, it may cause the CAS operation to be unsuccessful, and the For loop can be used multiple times.

Examples of Use:

var value Int64func Atomicaddop(tmp Int64) { for {       OldValue := value       if Atomic.CompareAndSwapInt64(&value, OldValue, OldValue+tmp) {           return       }   }}


Exchange

The prefixes for this type of operation are Swap :

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


In contrast to CAS, it is obvious that such operations are more violent and direct, regardless of whether the old value of the variable is changed, giving the new value directly and then returning the value replaced by the back.


Store

The prefixes for this type of operation are Store :

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

This kind of operation ensures the atomicity of the write variable, and avoids other operations reading dirty data in the process of modifying the variable.

Welcome to my personal public number: easyhacking

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.