...

Package atomic

import "sync/atomic"
概览
索引
示例

概览 ▾

atomic 包提供了底层的原子性内存原语,这对于同步算法的实现很有用.

这些函数一定要非常小心地,正确地使用。特别是对于底层应用来说,最好使用信道或 sync 包中提供的功能来完成。

不要通过共享内存来通信,应该通过通信来共享内存。

“比较并交换”操作由 CompareAndSwapT 函数实现,它在原子性上等价于:

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

“加上”操作由 AddT 函数实现,它在原子性上等价于:

*addr += delta
return *addr

“载入并存储”操作由 LoadT 函数和 StoreT 函数实现,它们在原子性上分别等价于:

"return *addr"

"*addr = val".

索引 ▾

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)
type Value
    func (v *Value) Load() (x interface{})
    func (v *Value) Store(x interface{})
Bugs

包文件

doc.go value.go

func AddInt32

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

AddInt32 自动将 delta 加上 *addr 并返回新值。

func AddInt64

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

AddInt64 自动将 delta 加上 *addr 并返回新值。

func AddUint32

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

AddUint32 自动将 delta 加上 *addr 并返回新值。 要从 x 中减去一个带符号正整数常量 c,需执行 AddUint32(&x, ^uint32(c-1))。 特别地,要减量 x,需执行 AddUint32(&x, ^uint32(0))。

func AddUint64

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

AddUint64 自动将 delta 加上 *addr 并返回新值。 要从 x 中减去一个带符号正整数常量 c,需执行 AddUint64(&x, ^uint64(c-1))。 特别地,要减量 x,需执行 AddUint64(&x, ^uint64(0))。

func AddUintptr

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

AddUintptr 自动将 delta 加上 *addr 并返回新值。

func CompareAndSwapInt32

func CompareAndSwapInt32(addr *int32, old, new int32) (swapped bool)

CompareAndSwapInt32 为一个 int32 类型的值执行“比较并交换”操作。

func CompareAndSwapInt64

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

CompareAndSwapInt64 为一个 int64 类型的值执行“比较并交换”操作。

func CompareAndSwapPointer

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

CompareAndSwapPointer 为一个 unsafe.Pointer 类型的值执行“比较并交换”操作。

func CompareAndSwapUint32

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

CompareAndSwapUint32 为一个 uint32 类型的值执行“比较并交换”操作。

func CompareAndSwapUint64

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

CompareAndSwapUint64 为一个 uint64 类型的值执行“比较并交换”操作。

func CompareAndSwapUintptr

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

CompareAndSwapUintptr 为一个 uintptr 类型的值执行“比较并交换”操作。

func LoadInt32

func LoadInt32(addr *int32) (val int32)

LoadInt32 自动载入 *addr。

func LoadInt64

func LoadInt64(addr *int64) (val int64)

LoadInt64 自动载入 *addr。

func LoadPointer

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

LoadPointer 自动载入 *addr。

func LoadUint32

func LoadUint32(addr *uint32) (val uint32)

LoadUint32 自动载入 *addr。

func LoadUint64

func LoadUint64(addr *uint64) (val uint64)

LoadUint64 自动载入 *addr。

func LoadUintptr

func LoadUintptr(addr *uintptr) (val uintptr)

LoadUintptr 自动载入 *addr。

func StoreInt32

func StoreInt32(addr *int32, val int32)

StoreInt32 自动将 val 存储到 *addr 中。

func StoreInt64

func StoreInt64(addr *int64, val int64)

StoreInt64 自动将 val 存储到 *addr 中。

func StorePointer

func StorePointer(addr *unsafe.Pointer, val unsafe.Pointer)

StorePointer 自动将 val 存储到 *addr 中。

func StoreUint32

func StoreUint32(addr *uint32, val uint32)

StoreUint32 自动将 val 存储到 *addr 中。

func StoreUint64

func StoreUint64(addr *uint64, val uint64)

StoreUint64 自动将 val 存储到 *addr 中。

func StoreUintptr

func StoreUintptr(addr *uintptr, val uintptr)

StoreUint64 自动将 val 存储到 *addr 中。

func SwapInt32

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

SwapInt32 自动将 new 存储到 *addr 中并返回上一个 *addr 值。

func SwapInt64

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

SwapInt64 自动将 new 存储到 *addr 中并返回上一个 *addr 值。

func SwapPointer

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

SwapPointer 自动将 new 存储到 *addr 中并返回上一个 *addr 值。

func SwapUint32

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

SwapUint32 自动将 new 存储到 *addr 中并返回上一个 *addr 值。

func SwapUint64

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

SwapUint64 自动将 new 存储到 *addr 中并返回上一个 *addr 值。

func SwapUintptr

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

SwapUintptr 自动将 new 存储到 *addr 中并返回上一个 *addr 值。

type Value

type Value struct {
    // contains filtered or unexported fields
}

A Value provides an atomic load and store of a consistently typed value. Values can be created as part of other data structures. The zero value for a Value returns nil from Load. Once Store has been called, a Value must not be copied.

示例 (Config)

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

代码:

var config Value // holds current server configuration
// Create initial config value and store into config.
config.Store(loadConfig())
go func() {
    // Reload config every 10 seconds
    // and update config value with the new version.
    for {
        time.Sleep(10 * time.Second)
        config.Store(loadConfig())
    }
}()
// Create worker goroutines that handle incoming requests
// using the latest config value.
for i := 0; i < 10; i++ {
    go func() {
        for r := range requests() {
            c := config.Load()
            // Handle request r using config c.
            _, _ = r, c
        }
    }()
}

示例 (ReadMostly)

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

代码:

type Map map[string]string
var m 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(key string) (val string) {
    m1 := m.Load().(Map)
    return m1[key]
}
// insert function can be used to update the data without further synchronization
insert := func(key, val string) {
    mu.Lock() // synchronize with other potential writers
    defer mu.Unlock()
    m1 := m.Load().(Map) // load current value of the data structure
    m2 := make(Map)      // create a new value
    for k, v := range m1 {
        m2[k] = v // copy all data from the current object to the new one
    }
    m2[key] = val // do the update that we need
    m.Store(m2)   // atomically replace the current object with the new one
    // At this point all new readers start working with the new version.
    // The old version will be garbage collected once the existing readers
    // (if any) are done with it.
}
_, _ = read, insert

func (*Value) Load

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

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

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

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

Bugs