//代码1:
var (
lock sync.Mutex
instance *UserInfo
)
func getInstance() (*UserInfo, error) {
if instance == nil {
//---Lock
lock.Lock()
defer lock.Unlock()
if instance == nil {
instance = &UserInfo{
Name: "fan",
}
}
}//---Unlock()
return instance, nil
}
我在网上看到这个代码,说是有数据竞争,在UserInfo赋值的阶段,解决方案:
代码2:
var flag uint32
func getInstance() (*UserInfo, error) {
if atomic.LoadUint32(&flag) != 1 {
lock.Lock()
defer lock.Unlock()
if instance == nil {
// 其他初始化错误,如果有错误可以直接返回
instance = &UserInfo{
Age: 18,
}
atomic.StoreUint32(&flag, 1)
}
}
return instance, nil
}
我有几个疑问:
1、使用atomic.LoadUint32原则性检查flag值有没有变化,如果在这一步换成mutex.Lock不行么,使用LoadUint32的判断,UserInfo的赋值一定是原子的么
2、在代码1的开始出加锁,是不是可以减少刚开始的if instance == nil 的判断,变成这样:
func getInstance() (*UserInfo, error) {
//---Lock
lock.Lock()
defer lock.Unlock()
instance = &UserInfo{
Name: "fan",
}
return instance, nil
}
这样有何不妥?
golang对结构体赋值的数据竞争
- 写回答
- 好问题 0 提建议
- 关注问题
- 邀请回答
-
3条回答 默认 最新
阿里嘎多学长 2025-10-30 20:17关注阿里嘎多学长整理AIGC生成,因移动端显示问题导致当前答案未能完全显示,请使用PC端查看更加详细的解答过程
数据竞争问题分析
你提到的代码1存在数据竞争问题。数据竞争是指多个 goroutine 同时访问共享资源时,可能导致的竞争和冲突。
在你的代码中,
lock是一个sync.Mutex,用于保护instance的访问。但是,在getInstance()函数中,lock并没有被正确地锁定和解锁。问题原因
问题原因在于
lock在getInstance()函数中没有被正确地锁定和解锁。具体来说,lock.Lock()和lock.Unlock()方法没有被正确地调用。解决方案
为了解决这个问题,我们需要在
getInstance()函数中正确地锁定和解锁lock。具体的解决方案如下:func getInstance() (*UserInfo, error) { lock.Lock() defer lock.Unlock() // ... }在上面的代码中,我们使用
defer关键字来确保lock.Unlock()方法在函数返回之前被调用,这样就可以确保lock被正确地解锁。最佳实践
为了避免数据竞争问题,我们应该遵循以下最佳实践:
- 使用
sync.Mutex或其他同步原语来保护共享资源的访问。 - 在函数中正确地锁定和解锁同步原语。
- 使用
defer关键字来确保同步原语被正确地解锁。
通过遵循这些最佳实践,我们可以避免数据竞争问题并确保程序的正确性和安全性。
本回答被题主选为最佳回答 , 对您是否有帮助呢?解决 无用评论 打赏 举报- 使用