以下是一个示例程序,用 Go 语言实现了一个共享自定义类型变量的无锁读写。
package main
import (
"sync/atomic"
"unsafe"
)
type Person struct {
Name string
Age int
}
type AtomicPerson struct {
p unsafe.Pointer
}
func NewAtomicPerson(p *Person) *AtomicPerson {
return &AtomicPerson{unsafe.Pointer(p)}
}
func (ap *AtomicPerson) Get() *Person {
return (*Person)(atomic.LoadPointer(&ap.p))
}
func (ap *AtomicPerson) Set(newp *Person) {
atomic.StorePointer(&ap.p, unsafe.Pointer(newp))
}
在这个示例中,我们定义了一个 Person
结构体类型,包含了一个姓名和一个年龄字段。然后我们又定义了一个 AtomicPerson
类型,这个类型包含了一个指针类型的 p
字段,用于存储被读写的 Person
类型对象的指针。
NewAtomicPerson
函数用于创建一个 AtomicPerson
类型的实例,参数 p
是一个 Person
类型的对象指针,用于初始化 AtomicPerson
实例中的 p
字段的值。
Get
方法用于获取被读取的 Person
类型对象的指针,这里使用了 Go 标准库中的原子指针操作函数 atomic.LoadPointer
。
Set
方法用于设置被写入的 Person
类型对象的指针,这里使用了 Go 标准库中的原子指针操作函数 atomic.StorePointer
。
值得注意的是,由于 Go 语言中的 map
、slice
、chan
等类型都不是内存对齐的类型,因此不能被原子读写,只有内存对齐的类型才能被原子读写,如 string
、struct
等类型。在使用原子操作时,也需要验证类型是否是内存对齐的。