有一个parm,读取更多,写得更少,而且我不想使用互斥锁。我通过unsafe
和atomic
完成了这样的操作:
type tmp struct {
}
var value unsafe.Pointer
func GetValue() *tmp {
return (*tmp)(atomic.LoadPointer(&value))
}
func SetValue(p *tmp) {
atomic.StorePointer(&value, unsafe.Pointer(p))
}
这是线程安全的吗?和atomic.StorePointer happen before
atomic.LoadPointer?
答案 0 :(得分:2)
在某种意义上它是线程安全的,你不知道先发生了什么,但更新是原子的。您是否考虑过使用RWMutex?除非有写入,否则这不会锁定读者。
答案 1 :(得分:2)
据我所知,使用atomic.LoadPointer和atomic.StorePointer存储和检索指针是线程安全的(在指针本身不会被破坏的意义上)。
当然,指向的对象必须是不可变的,并且这种机制不强制执行。这是您的工作,以确保在调用UpdateConfig之前更新配置将导致创建新对象。
但是,主要问题是代码依赖于不安全的操作。使其类型安全是困难的,因为实际上存储了两个指针(一个用于对象,一个用于类型)。原子指针操作不再足以保证一致性。
这就是最近在同步/原子包中添加特定类型的原因:the sync.Value type。它的设计完全符合您的要求(即优化对大多数常量数据的访问)。
您可以在此处找到示例:http://golang.org/pkg/sync/atomic/#example_Value_config
如果你查看implementation,你会发现为什么单独的原子指针操作不足以实现类型安全机制。
答案 2 :(得分:0)
根据https://code.google.com/p/go/issues/detail?id=5045
Regarding Add/CAS, it should be formulated in in more general terms, along the
lines of: at atomic operation that stores a value (incl ADD/CAS) happens before
atomic operation that reads that value from the memory location (incl ADD/CAS).
我认为我们可以使用atomic来确保它是线程安全的。