首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

原子操作 | sync/atomic

  • import "sync/atomic"
  • 概观
  • 索引
  • 示例

概观

Package atomic 提供了用于实现同步算法的低级原子内存原语。

这些功能需要非常小心才能正确使用。除特殊的低级别应用程序外,同步更适合使用频道或同步软件包的功能。通过沟通共享内存; 不要通过共享内存进行通信。

由 SwapT 函数实现的交换操作是以下原子等值:

代码语言:javascript
复制
old = *addr
*addr = new
return old

由 CompareAndSwapT 函数实现的比较和交换操作与以下原子等价:

代码语言:javascript
复制
if *addr == old {
	*addr = new
	return true
}
return false

由 Add T函数实现的 add 操作与以下操作相当:

代码语言:javascript
复制
*addr += delta
return *addr

由 LoadT 和 StoreT 函数实现的加载和存储操作是 "return *addr" and "*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{})
  • 错误

示例

Value (Config) Value (ReadMostly)

打包文件

func AddInt32Source

代码语言:javascript
复制
func AddInt32(addr *int32, delta int32) (new int32)

AddInt32 自动地将增量添加到 * addr 并返回新值。

func AddInt64Source

代码语言:javascript
复制
func AddInt64(addr *int64, delta int64) (new int64)

AddInt64 自动地将增量添加到 * addr 并返回新值。

func AddUint32Source

代码语言:javascript
复制
func AddUint32(addr *uint32, delta uint32) (new uint32)

AddUint32 自动地将增量添加到 * addr 并返回新值。要从 x 中减去一个带符号的正常数值 c ,请执行 AddUint32(&x, ^uint32(c-1))。特别是,要减少 x ,请执行 AddUint32(&x, ^uint32(0)) 。

func AddUint64Source

代码语言:javascript
复制
func AddUint64(addr *uint64, delta uint64) (new uint64)

AddUint64 自动地将增量添加到 * addr 并返回新值。要从 x 中减去一个带符号的正常数值 c ,请执行 AddUint64(&x, ^uint64(c-1))。特别是,要减少 x ,请执行 AddUint64(&x, ^uint64(0)) 。

func AddUintptrSource

代码语言:javascript
复制
func AddUintptr(addr *uintptr, delta uintptr) (new uintptr)

AddUintptr 自动向 delta addr 添加 delta 并返回新值。

func CompareAndSwapInt32Source

代码语言:javascript
复制
func CompareAndSwapInt32(addr *int32, old, new int32) (swapped bool)

CompareAndSwapInt32 为 int32 值执行比较和交换操作。

func CompareAndSwapInt64Source

代码语言:javascript
复制
func CompareAndSwapInt64(addr *int64, old, new int64) (swapped bool)

CompareAndSwapInt64 为 int64 值执行比较和交换操作。

func CompareAndSwapPointerSource

代码语言:javascript
复制
func CompareAndSwapPointer(addr *unsafe.Pointer, old, new unsafe.Pointer) (swapped bool)

CompareAndSwapPointer 对不安全的指针值执行比较和交换操作。

func CompareAndSwapUint32Source

代码语言:javascript
复制
func CompareAndSwapUint32(addr *uint32, old, new uint32) (swapped bool)

CompareAndSwapUint32 为 uint32 值执行比较和交换操作。

func CompareAndSwapUint64Source

代码语言:javascript
复制
func CompareAndSwapUint64(addr *uint64, old, new uint64) (swapped bool)

CompareAndSwapUint64 为 uint64 值执行比较和交换操作。

func CompareAndSwapUintptrSource

代码语言:javascript
复制
func CompareAndSwapUintptr(addr *uintptr, old, new uintptr) (swapped bool)

CompareAndSwapUintptr 为 uintptr 值执行比较和交换操作。

func LoadInt32Source

代码语言:javascript
复制
func LoadInt32(addr *int32) (val int32)

LoadInt32 自动加载 * addr 。

func LoadInt64Source

代码语言:javascript
复制
func LoadInt64(addr *int64) (val int64)

LoadInt64 自动加载 * addr 。

func LoadPointerSource

代码语言:javascript
复制
func LoadPointer(addr *unsafe.Pointer) (val unsafe.Pointer)

LoadPointer atomically loads *addr.

func LoadUint32Source

代码语言:javascript
复制
func LoadUint32(addr *uint32) (val uint32)

LoadUint32 自动加载 * addr 。

func LoadUint64Source

代码语言:javascript
复制
func LoadUint64(addr *uint64) (val uint64)

LoadUint64 自动地加载 * addr 。

func LoadUintptrSource

代码语言:javascript
复制
func LoadUintptr(addr *uintptr) (val uintptr)

LoadUintptr 自动加载 * addr 。

func StoreInt32Source

代码语言:javascript
复制
func StoreInt32(addr *int32, val int32)

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

func StoreInt64Source

代码语言:javascript
复制
func StoreInt64(addr *int64, val int64)

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

func StorePointerSource

代码语言:javascript
复制
func StorePointer(addr *unsafe.Pointer, val unsafe.Pointer)

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

func StoreUint32Source

代码语言:javascript
复制
func StoreUint32(addr *uint32, val uint32)

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

func StoreUint64Source

代码语言:javascript
复制
func StoreUint64(addr *uint64, val uint64)

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

func StoreUintptrSource

代码语言:javascript
复制
func StoreUintptr(addr *uintptr, val uintptr)

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

func SwapInt32Source

代码语言:javascript
复制
func SwapInt32(addr *int32, new int32) (old int32)

SwapInt32 将自动地新成员存储到 * addr 并返回以前的 * addr 值。

func SwapInt64Source

代码语言:javascript
复制
func SwapInt64(addr *int64, new int64) (old int64)

SwapInt64 自动地将新的值存储到 * addr 并返回前一个 * addr 值。

func SwapPointerSource

代码语言:javascript
复制
func SwapPointer(addr *unsafe.Pointer, new unsafe.Pointer) (old unsafe.Pointer)

SwapPointer 自动地将新的值存储到 * addr 并返回以前的 * addr 值。

func SwapUint32Source

代码语言:javascript
复制
func SwapUint32(addr *uint32, new uint32) (old uint32)

SwapUint32 自动地将新的值存储到 * addr 并返回前一个 * addr 值。

func SwapUint64Source

代码语言:javascript
复制
func SwapUint64(addr *uint64, new uint64) (old uint64)

SwapUint64 自动地将新的值存储到 * addr 中,并返回以前的 * addr 值。

func SwapUintptrSource

代码语言:javascript
复制
func SwapUintptr(addr *uintptr, new uintptr) (old uintptr)

SwapUintptr 自动地将新值存储到 * addr 中,并返回前一个 * addr 值。

type ValueSource

值提供了一个自动加载和一个一致的类型值的存储。Value 的零值从 Load 返回 nil 。一旦 Store 被调用,Value 不能被复制。

首次使用后不得复制 Value 。

代码语言:javascript
复制
type Value struct {
        // contains filtered or unexported fields
}

示例(配置)

以下示例显示如何使用 Value 进行周期性程序配置更新以及将更改传播到工作程序。

编码:

代码语言:javascript
复制
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)

以下示例说明如何使用写入时复制习惯用法维护可扩展的经常读取但不经常更新的数据结构。

编码:

代码语言:javascript
复制
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) LoadSource

代码语言:javascript
复制
func (v *Value) Load() (x interface{})

Load 返回最近的存储设置的值。如果此值没有存储调用,则返回 nil 。

func (*Value) StoreSource

代码语言:javascript
复制
func (v *Value) Store(x interface{})

Store 将 Value 的值设置为 x 。对于给定值的所有对 Store的调用都必须使用相同具体类型的值。存储不一致的类型恐慌,就像 Store(nil) 一样。

错误

  • 在x86-32上,64位函数使用 Pentium MMX 之前不可用的指令。

在非 Linux ARM 上,64位函数使用 ARMv6k 内核之前不可用的指令。

在 ARM 和 x86-32 上,调用者都有责任安排自动访问64位字的64位对齐方式。变量或分配的结构,数组或片中的第一个字可以依赖于64位对齐。

扫码关注腾讯云开发者

领取腾讯云代金券