Overview

包atomic提供了底层原子atomic memory原语,用于实现同步算法. 这些函数要求格外的小心才能正确使用.除了特别的底层应用,同步最好使用通道或sync包的使用.通过交流共享内存,而不是为了交流去共享内存. 交换操作,被SwapT函数实现,它等价于:
old = *addr
addr = new
return old

比较和交换操作,通过CompareAndSwapT函数实现,等价于原子性的:

if *addr == old {
    *addr = new
    return true
}
return false

增加操作,通过AddT实现,等价于原子性的:

*addr += delta
return *addr

加载和存储操作,由LoadT和StoreT实现,等价于原子性的”return *addr”和”*addr = val”

func AddInt32(data *int32, delta int32) (new int32)

将data原子性的增加delta,并返回其值

func AddInt64(data *int64, delta int64) (new int64)

将data原子性的增加delta,并返回其值

func AddUint32(data *uint32, delta uint32) (new uint32)

将data原子性的增加delta,并返回其值

func AddUint64(data *uint64, delta uint64) (new uint64)

将data原子性的增加delta,并返回其值

func AddUintptr(addr *uintptr, delta uintptr) (new uintptr)

将addr原子性的增加delta,并返回其值

func CompareAndSwapInt32(addr *int, old, new int32) (swaped bool)

如果值和old相同,则将addr和new原子性的交换,并返回是否交换

func CompareAndSwapInt64(addr *int64, old, new int64) (swapped bool)

如果值和old相同,则将add和new原子性的交换,并返回是否交换

func CompareAndSwapUint32(addr *uint32, old, new uint32) (swapped bool)

如果值和old相同,则将add和new原子性的交换,并返回是否交换

func CompareAndSwapUint64(addr *uint64, old, new uint64) (swapped bool)

如果值和old相同,则将add和new原子性的交换,并返回是否交换

func CompareAndSwapUintptr(addr *uintptr, old, new uintptr) (swapped bool)

如果值和old相同,则将add和new原子性的交换,并返回是否交换

func CompareAndSwapPointer(addr *unsafe.Pointer, old, new unsafe.Pointer) (swapped bool)

如果值和old相同,则将add和new原子性的交换,并返回是否交换

func LoadInt32(addr *int32) (val int32)

加载addr数据

func LoadInt64(addr *int64) (val int64)

加载addr数据

func LoadUint32(addr *uint32) (val uint32)

加载addr数据

func LoadUint64(addr *uint64) (val uint64)

加载addr数据

func LoadPointer(addr *unsafe.Pointer) (val unsafe.Pointer)

加载addr数据

func LoadUintptr(addr *uintptr) (val uintptr)

加载addr数据

func StoreInt32(addr *int32, val int32)

原子性的将val存储到addr

func StoreInt64(addr *int64, val int64)

原子性的将val存储到addr

func StoreUint32(addr *uint32, val uint32)

原子性的将val存储到addr

func StoreUint64(addr *uint64, val uint64)

func StoreUintptr(addr *uint64, val uintptr)

StoreUintptr原子性的存储val到addr

func SwapInt32(addr *int32, new int32) (old int32)

SwapInt32原子性的存储new到*addr,并返回原来的*addr

func SwapInt64(addr *int64, new int64) (old int64)

SwapInt64原子性的存储new到*addr,并返回原来的*addr

func SwapUint32(addr *uint32, new uint32) (old uint32)

SwapUint32原子性的存储new到*addr,并返回原来的*addr

func SwapUint64(addr *uint64, new uint64) (old uint64)

SwapUint64原子性的存储new到*addr,并返回原来的*addr

func SwapUintptr(addr *uintptr, new uintptr) (old uintptr)

SwapUintptr原子性的存储new到*addr,并返回原来的*addr

func SwapPointer(addr *unsafe.Pointer, new unsafe.Pointer) (old unsafe.Pointer)

SwapPointer原子性的存储new到*addr,并返回原来的*addr

type Value


type Value struct {
    // contains filtered or unexported fields
}
Value提供了原子性的加载和存储的一致性类型,Value的零值从Value返回nil,一旦Store调用,Value将不能被复制. Value使用后必须不能被复制

func (v *Value) Load() (x interface{})

Load返回最近Store设置的值,如果没有调用过Store返回nil

func (v *Value) Store(x interface{})

设置Value的值为x,所有调用Store给出的值必须是固定的类型,设置不一致的类型将会panic,比如Store(nil)

Example


package main

import (
	"sync"
	"fmt"
)

func main() {
	var done sync.WaitGroup
	done.Add(2)
	firstPipe := 0
	secondPipe := 0
	go func() {
		for i := 0; i < 50; i++ {
			firstPipe++
		}
		done.Done()
	}()
	go func() {
		for i := 0; i < 200; i++ {
			secondPipe++
		}
		done.Done()
	}()
	done.Wait()
	fmt.Println("total: ", (firstPipe + secondPipe))
}

Example

package main

import (
	"sync"
	"sync/atomic"
	"fmt"
)

func main() {
	var counter int32 = 0
	// for add 2
	times := 100000
	var done sync.WaitGroup
	done.Add(2)
	go func() {
		for i := 0; i < times; i++ {
			atomic.AddInt32(&counter, 2)
		}
		defer done.Done()
	}()
	// for sub 1
	go func() {
		for i := 0; i < times; i++ {
			atomic.AddInt32(&counter, -1)
		}
		defer done.Done()
	}()
	done.Wait()
	fmt.Println("counter: ", counter, "times: ", times)
}